1
// 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.
20
HyperDrive DriveType = iota
24
type Passenger struct {
25
Name []string `xml:"name"`
26
Weight float32 `xml:"weight"`
30
XMLName Name `xml:"spaceship"`
32
Name string `xml:"attr"`
33
Pilot string `xml:"attr"`
34
Drive DriveType `xml:"drive"`
36
Passenger []*Passenger `xml:"passenger"`
42
func (rx RawXML) MarshalXML() ([]byte, os.Error) {
43
return []byte(rx), nil
49
XMLName Name `xml:"port"`
50
Type string `xml:"attr"`
51
Number string `xml:"chardata"`
55
XMLName Name `xml:"domain"`
56
Country string `xml:"attr"`
57
Name []byte `xml:"chardata"`
60
type SecretAgent struct {
61
XMLName Name `xml:"agent"`
62
Handle string `xml:"attr"`
64
Obfuscate string `xml:"innerxml"`
69
var marshalTests = []struct {
73
// Test nil marshals to nothing
74
{Value: nil, ExpectXML: ``},
75
{Value: nilStruct, ExpectXML: ``},
77
// Test value types (no tag name, so ???)
78
{Value: true, ExpectXML: `<???>true</???>`},
79
{Value: int(42), ExpectXML: `<???>42</???>`},
80
{Value: int8(42), ExpectXML: `<???>42</???>`},
81
{Value: int16(42), ExpectXML: `<???>42</???>`},
82
{Value: int32(42), ExpectXML: `<???>42</???>`},
83
{Value: uint(42), ExpectXML: `<???>42</???>`},
84
{Value: uint8(42), ExpectXML: `<???>42</???>`},
85
{Value: uint16(42), ExpectXML: `<???>42</???>`},
86
{Value: uint32(42), ExpectXML: `<???>42</???>`},
87
{Value: float32(1.25), ExpectXML: `<???>1.25</???>`},
88
{Value: float64(1.25), ExpectXML: `<???>1.25</???>`},
89
{Value: uintptr(0xFFDD), ExpectXML: `<???>65501</???>`},
90
{Value: "gopher", ExpectXML: `<???>gopher</???>`},
91
{Value: []byte("gopher"), ExpectXML: `<???>gopher</???>`},
92
{Value: "</>", ExpectXML: `<???></></???>`},
93
{Value: []byte("</>"), ExpectXML: `<???></></???>`},
94
{Value: [3]byte{'<', '/', '>'}, ExpectXML: `<???></></???>`},
95
{Value: NamedType("potato"), ExpectXML: `<???>potato</???>`},
96
{Value: []int{1, 2, 3}, ExpectXML: `<???>1</???><???>2</???><???>3</???>`},
97
{Value: [3]int{1, 2, 3}, ExpectXML: `<???>1</???><???>2</???><???>3</???>`},
100
{Value: RawXML("</>"), ExpectXML: `</>`},
104
Identity: "James Bond",
105
Obfuscate: "<redacted/>",
107
//ExpectXML: `<agent handle="007"><redacted/></agent>`,
108
ExpectXML: `<agent handle="007"><Identity>James Bond</Identity><redacted/></agent>`,
112
{Value: &Port{Type: "ssl", Number: "443"}, ExpectXML: `<port type="ssl">443</port>`},
113
{Value: &Port{Number: "443"}, ExpectXML: `<port>443</port>`},
114
{Value: &Port{Type: "<unix>"}, ExpectXML: `<port type="<unix>"></port>`},
115
{Value: &Domain{Name: []byte("google.com&friends")}, ExpectXML: `<domain>google.com&friends</domain>`},
116
{Value: atomValue, ExpectXML: atomXml},
119
Name: "Heart of Gold",
122
Drive: ImprobabilityDrive,
123
Passenger: []*Passenger{
125
Name: []string{"Zaphod", "Beeblebrox"},
129
Name: []string{"Trisha", "McMillen"},
133
Name: []string{"Ford", "Prefect"},
137
Name: []string{"Arthur", "Dent"},
142
ExpectXML: `<spaceship name="Heart of Gold" pilot="Computer">` +
143
`<drive>` + strconv.Itoa(int(ImprobabilityDrive)) + `</drive>` +
146
`<name>Zaphod</name>` +
147
`<name>Beeblebrox</name>` +
148
`<weight>7.25</weight>` +
151
`<name>Trisha</name>` +
152
`<name>McMillen</name>` +
153
`<weight>5.5</weight>` +
156
`<name>Ford</name>` +
157
`<name>Prefect</name>` +
158
`<weight>7</weight>` +
161
`<name>Arthur</name>` +
162
`<name>Dent</name>` +
163
`<weight>6.75</weight>` +
169
func TestMarshal(t *testing.T) {
170
for idx, test := range marshalTests {
171
buf := bytes.NewBuffer(nil)
172
err := Marshal(buf, test.Value)
174
t.Errorf("#%d: Error: %s", idx, err)
177
if got, want := buf.String(), test.ExpectXML; got != want {
178
if strings.Contains(want, "\n") {
179
t.Errorf("#%d: marshal(%#v) - GOT:\n%s\nWANT:\n%s", idx, test.Value, got, want)
181
t.Errorf("#%d: marshal(%#v) = %#q want %#q", idx, test.Value, got, want)
187
var marshalErrorTests = []struct {
190
ExpectKind reflect.Kind
193
Value: make(chan bool),
194
ExpectErr: "xml: unsupported type: chan bool",
195
ExpectKind: reflect.Chan,
198
Value: map[string]string{
199
"question": "What do you get when you multiply six by nine?",
202
ExpectErr: "xml: unsupported type: map[string] string",
203
ExpectKind: reflect.Map,
206
Value: map[*Ship]bool{nil: false},
207
ExpectErr: "xml: unsupported type: map[*xml.Ship] bool",
208
ExpectKind: reflect.Map,
212
func TestMarshalErrors(t *testing.T) {
213
for idx, test := range marshalErrorTests {
214
buf := bytes.NewBuffer(nil)
215
err := Marshal(buf, test.Value)
216
if got, want := err, test.ExpectErr; got == nil {
217
t.Errorf("#%d: want error %s", idx, want)
219
} else if got.String() != want {
220
t.Errorf("#%d: marshal(%#v) = [error] %q, want %q", idx, test.Value, got, want)
222
if got, want := err.(*UnsupportedTypeError).Type.Kind(), test.ExpectKind; got != want {
223
t.Errorf("#%d: marshal(%#v) = [error kind] %s, want %s", idx, test.Value, got, want)
228
// Do invertibility testing on the various structures that we test
229
func TestUnmarshal(t *testing.T) {
230
for i, test := range marshalTests {
231
// Skip the nil pointers
238
switch test.Value.(type) {
243
case *Domain, Domain:
251
buffer := bytes.NewBufferString(test.ExpectXML)
252
err := Unmarshal(buffer, dest)
254
// Don't compare XMLNames
255
switch fix := dest.(type) {
264
fix.Author.InnerXML = ""
265
for i := range fix.Entry {
266
fix.Entry[i].Author.InnerXML = ""
271
t.Errorf("#%d: unexpected error: %#v", i, err)
272
} else if got, want := dest, test.Value; !reflect.DeepEqual(got, want) {
273
t.Errorf("#%d: unmarshal(%#s) = %#v, want %#v", i, test.ExpectXML, got, want)
278
func BenchmarkMarshal(b *testing.B) {
279
idx := len(marshalTests) - 1
280
test := marshalTests[idx]
282
buf := bytes.NewBuffer(nil)
283
for i := 0; i < b.N; i++ {
284
Marshal(buf, test.Value)
289
func BenchmarkUnmarshal(b *testing.B) {
290
idx := len(marshalTests) - 1
291
test := marshalTests[idx]
293
xml := []byte(test.ExpectXML)
295
for i := 0; i < b.N; i++ {
296
buffer := bytes.NewBuffer(xml)
297
Unmarshal(buffer, sm)