From 5ff4c17907d5b19510a62e08fd8d3b11e62b431d Mon Sep 17 00:00:00 2001 From: Ondřej Surý Date: Tue, 13 Sep 2011 13:13:40 +0200 Subject: Imported Upstream version 60 --- src/pkg/xml/marshal_test.go | 305 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 305 insertions(+) create mode 100644 src/pkg/xml/marshal_test.go (limited to 'src/pkg/xml/marshal_test.go') diff --git a/src/pkg/xml/marshal_test.go b/src/pkg/xml/marshal_test.go new file mode 100644 index 000000000..5b972fafe --- /dev/null +++ b/src/pkg/xml/marshal_test.go @@ -0,0 +1,305 @@ +// 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 xml + +import ( + "reflect" + "testing" + + "os" + "bytes" + "strings" + "strconv" +) + +type DriveType int + +const ( + HyperDrive DriveType = iota + ImprobabilityDrive +) + +type Passenger struct { + Name []string `xml:"name"` + Weight float32 `xml:"weight"` +} + +type Ship struct { + XMLName Name `xml:"spaceship"` + + Name string `xml:"attr"` + Pilot string `xml:"attr"` + Drive DriveType `xml:"drive"` + Age uint `xml:"age"` + Passenger []*Passenger `xml:"passenger"` + secret string +} + +type RawXML string + +func (rx RawXML) MarshalXML() ([]byte, os.Error) { + return []byte(rx), nil +} + +type NamedType string + +type Port struct { + XMLName Name `xml:"port"` + Type string `xml:"attr"` + Number string `xml:"chardata"` +} + +type Domain struct { + XMLName Name `xml:"domain"` + Country string `xml:"attr"` + Name []byte `xml:"chardata"` +} + +type Book struct { + XMLName Name `xml:"book"` + Title string `xml:"chardata"` +} + +type SecretAgent struct { + XMLName Name `xml:"agent"` + Handle string `xml:"attr"` + Identity string + Obfuscate string `xml:"innerxml"` +} + +var nilStruct *Ship + +var marshalTests = []struct { + Value interface{} + ExpectXML string +}{ + // Test nil marshals to nothing + {Value: nil, ExpectXML: ``}, + {Value: nilStruct, ExpectXML: ``}, + + // Test value types (no tag name, so ???) + {Value: true, ExpectXML: `true`}, + {Value: int(42), ExpectXML: `42`}, + {Value: int8(42), ExpectXML: `42`}, + {Value: int16(42), ExpectXML: `42`}, + {Value: int32(42), ExpectXML: `42`}, + {Value: uint(42), ExpectXML: `42`}, + {Value: uint8(42), ExpectXML: `42`}, + {Value: uint16(42), ExpectXML: `42`}, + {Value: uint32(42), ExpectXML: `42`}, + {Value: float32(1.25), ExpectXML: `1.25`}, + {Value: float64(1.25), ExpectXML: `1.25`}, + {Value: uintptr(0xFFDD), ExpectXML: `65501`}, + {Value: "gopher", ExpectXML: `gopher`}, + {Value: []byte("gopher"), ExpectXML: `gopher`}, + {Value: "", ExpectXML: `</>`}, + {Value: []byte(""), ExpectXML: `</>`}, + {Value: [3]byte{'<', '/', '>'}, ExpectXML: `</>`}, + {Value: NamedType("potato"), ExpectXML: `potato`}, + {Value: []int{1, 2, 3}, ExpectXML: `123`}, + {Value: [3]int{1, 2, 3}, ExpectXML: `123`}, + + // Test innerxml + {Value: RawXML(""), ExpectXML: ``}, + { + Value: &SecretAgent{ + Handle: "007", + Identity: "James Bond", + Obfuscate: "", + }, + //ExpectXML: ``, + ExpectXML: `James Bond`, + }, + + // Test structs + {Value: &Port{Type: "ssl", Number: "443"}, ExpectXML: `443`}, + {Value: &Port{Number: "443"}, ExpectXML: `443`}, + {Value: &Port{Type: ""}, ExpectXML: ``}, + {Value: &Domain{Name: []byte("google.com&friends")}, ExpectXML: `google.com&friends`}, + {Value: &Book{Title: "Pride & Prejudice"}, ExpectXML: `Pride & Prejudice`}, + {Value: atomValue, ExpectXML: atomXml}, + { + Value: &Ship{ + Name: "Heart of Gold", + Pilot: "Computer", + Age: 1, + Drive: ImprobabilityDrive, + Passenger: []*Passenger{ + &Passenger{ + Name: []string{"Zaphod", "Beeblebrox"}, + Weight: 7.25, + }, + &Passenger{ + Name: []string{"Trisha", "McMillen"}, + Weight: 5.5, + }, + &Passenger{ + Name: []string{"Ford", "Prefect"}, + Weight: 7, + }, + &Passenger{ + Name: []string{"Arthur", "Dent"}, + Weight: 6.75, + }, + }, + }, + ExpectXML: `` + + `` + strconv.Itoa(int(ImprobabilityDrive)) + `` + + `1` + + `` + + `Zaphod` + + `Beeblebrox` + + `7.25` + + `` + + `` + + `Trisha` + + `McMillen` + + `5.5` + + `` + + `` + + `Ford` + + `Prefect` + + `7` + + `` + + `` + + `Arthur` + + `Dent` + + `6.75` + + `` + + ``, + }, +} + +func TestMarshal(t *testing.T) { + for idx, test := range marshalTests { + buf := bytes.NewBuffer(nil) + err := Marshal(buf, test.Value) + if err != nil { + t.Errorf("#%d: Error: %s", idx, err) + continue + } + if got, want := buf.String(), test.ExpectXML; got != want { + if strings.Contains(want, "\n") { + t.Errorf("#%d: marshal(%#v) - GOT:\n%s\nWANT:\n%s", idx, test.Value, got, want) + } else { + t.Errorf("#%d: marshal(%#v) = %#q want %#q", idx, test.Value, got, want) + } + } + } +} + +var marshalErrorTests = []struct { + Value interface{} + ExpectErr string + ExpectKind reflect.Kind +}{ + { + Value: make(chan bool), + ExpectErr: "xml: unsupported type: chan bool", + ExpectKind: reflect.Chan, + }, + { + Value: map[string]string{ + "question": "What do you get when you multiply six by nine?", + "answer": "42", + }, + ExpectErr: "xml: unsupported type: map[string] string", + ExpectKind: reflect.Map, + }, + { + Value: map[*Ship]bool{nil: false}, + ExpectErr: "xml: unsupported type: map[*xml.Ship] bool", + ExpectKind: reflect.Map, + }, +} + +func TestMarshalErrors(t *testing.T) { + for idx, test := range marshalErrorTests { + buf := bytes.NewBuffer(nil) + err := Marshal(buf, test.Value) + if got, want := err, test.ExpectErr; got == nil { + t.Errorf("#%d: want error %s", idx, want) + continue + } else if got.String() != want { + t.Errorf("#%d: marshal(%#v) = [error] %q, want %q", idx, test.Value, got, want) + } + if got, want := err.(*UnsupportedTypeError).Type.Kind(), test.ExpectKind; got != want { + t.Errorf("#%d: marshal(%#v) = [error kind] %s, want %s", idx, test.Value, got, want) + } + } +} + +// Do invertibility testing on the various structures that we test +func TestUnmarshal(t *testing.T) { + for i, test := range marshalTests { + // Skip the nil pointers + if i <= 1 { + continue + } + + var dest interface{} + + switch test.Value.(type) { + case *Ship, Ship: + dest = &Ship{} + case *Port, Port: + dest = &Port{} + case *Domain, Domain: + dest = &Domain{} + case *Feed, Feed: + dest = &Feed{} + default: + continue + } + + buffer := bytes.NewBufferString(test.ExpectXML) + err := Unmarshal(buffer, dest) + + // Don't compare XMLNames + switch fix := dest.(type) { + case *Ship: + fix.XMLName = Name{} + case *Port: + fix.XMLName = Name{} + case *Domain: + fix.XMLName = Name{} + case *Feed: + fix.XMLName = Name{} + 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(%#s) = %#v, want %#v", i, test.ExpectXML, got, want) + } + } +} + +func BenchmarkMarshal(b *testing.B) { + idx := len(marshalTests) - 1 + test := marshalTests[idx] + + buf := bytes.NewBuffer(nil) + for i := 0; i < b.N; i++ { + Marshal(buf, test.Value) + buf.Truncate(0) + } +} + +func BenchmarkUnmarshal(b *testing.B) { + idx := len(marshalTests) - 1 + test := marshalTests[idx] + sm := &Ship{} + xml := []byte(test.ExpectXML) + + for i := 0; i < b.N; i++ { + buffer := bytes.NewBuffer(xml) + Unmarshal(buffer, sm) + } +} -- cgit v1.2.3