|
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. |
|
4 |
|
5 package xmpp |
|
6 |
|
7 import ( |
|
8 "bytes" |
|
9 "encoding/xml" |
|
10 "fmt" |
|
11 "os" |
|
12 "reflect" |
|
13 "runtime" |
|
14 "strings" |
|
15 "testing" |
|
16 ) |
|
17 |
|
18 func assertEquals(t *testing.T, expected, observed string) { |
|
19 if expected != observed { |
|
20 file := "unknown" |
|
21 line := 0 |
|
22 _, file, line, _ = runtime.Caller(1) |
|
23 fmt.Fprintf(os.Stderr, "%s:%d: Expected:\n%s\nObserved:\n%s\n", |
|
24 file, line, expected, observed) |
|
25 t.Fail() |
|
26 } |
|
27 } |
|
28 |
|
29 func TestJid(t *testing.T) { |
|
30 str := "user@domain/res" |
|
31 jid := &JID{} |
|
32 if err := jid.Set(str); err != nil { |
|
33 t.Errorf("Set(%s) failed: %s", str, err) |
|
34 } |
|
35 assertEquals(t, "user", jid.Node) |
|
36 assertEquals(t, "domain", jid.Domain) |
|
37 assertEquals(t, "res", jid.Resource) |
|
38 assertEquals(t, str, jid.String()) |
|
39 |
|
40 str = "domain.tld" |
|
41 if err := jid.Set(str); err != nil { |
|
42 t.Errorf("Set(%s) failed: %s", str, err) |
|
43 } |
|
44 if jid.Node != "" { |
|
45 t.Errorf("Node: %v\n", jid.Node) |
|
46 } |
|
47 assertEquals(t, "domain.tld", jid.Domain) |
|
48 if jid.Resource != "" { |
|
49 t.Errorf("Resource: %v\n", jid.Resource) |
|
50 } |
|
51 assertEquals(t, str, jid.String()) |
|
52 } |
|
53 |
|
54 func assertMarshal(t *testing.T, expected string, marshal interface{}) { |
|
55 var buf bytes.Buffer |
|
56 enc := xml.NewEncoder(&buf) |
|
57 err := enc.Encode(marshal) |
|
58 if err != nil { |
|
59 t.Errorf("Marshal error for %s: %s", marshal, err) |
|
60 } |
|
61 observed := buf.String() |
|
62 if expected != observed { |
|
63 file := "unknown" |
|
64 line := 0 |
|
65 _, file, line, _ = runtime.Caller(1) |
|
66 fmt.Fprintf(os.Stderr, "%s:%d: Expected:\n%s\nObserved:\n%s\n", |
|
67 file, line, expected, observed) |
|
68 t.Fail() |
|
69 } |
|
70 } |
|
71 |
|
72 func TestStreamMarshal(t *testing.T) { |
|
73 s := &stream{To: "bob"} |
|
74 exp := `<stream:stream xmlns="` + NsClient + |
|
75 `" xmlns:stream="` + NsStream + `" to="bob">` |
|
76 assertEquals(t, exp, s.String()) |
|
77 |
|
78 s = &stream{To: "bob", From: "alice", Id: "#3", Version: "5.3"} |
|
79 exp = `<stream:stream xmlns="` + NsClient + |
|
80 `" xmlns:stream="` + NsStream + `" to="bob" from="alice"` + |
|
81 ` id="#3" version="5.3">` |
|
82 assertEquals(t, exp, s.String()) |
|
83 |
|
84 s = &stream{Lang: "en_US"} |
|
85 exp = `<stream:stream xmlns="` + NsClient + |
|
86 `" xmlns:stream="` + NsStream + `" xml:lang="en_US">` |
|
87 assertEquals(t, exp, s.String()) |
|
88 } |
|
89 |
|
90 func TestStreamErrorMarshal(t *testing.T) { |
|
91 name := xml.Name{Space: NsStreams, Local: "ack"} |
|
92 e := &streamError{Any: Generic{XMLName: name}} |
|
93 exp := `<error xmlns="` + NsStream + `"><ack xmlns="` + NsStreams + |
|
94 `"></ack></error>` |
|
95 assertMarshal(t, exp, e) |
|
96 |
|
97 txt := errText{Lang: "pt", Text: "things happen"} |
|
98 e = &streamError{Any: Generic{XMLName: name}, Text: &txt} |
|
99 exp = `<error xmlns="` + NsStream + `"><ack xmlns="` + NsStreams + |
|
100 `"></ack><text xmlns="` + NsStreams + |
|
101 `" xml:lang="pt">things happen</text></error>` |
|
102 assertMarshal(t, exp, e) |
|
103 } |
|
104 |
|
105 func TestIqMarshal(t *testing.T) { |
|
106 iq := &Iq{Header: Header{Type: "set", Id: "3", |
|
107 Nested: []interface{}{Generic{XMLName: xml.Name{Space: NsBind, |
|
108 Local: "bind"}}}}} |
|
109 exp := `<iq id="3" type="set"><bind xmlns="` + NsBind + |
|
110 `"></bind></iq>` |
|
111 assertMarshal(t, exp, iq) |
|
112 } |
|
113 |
|
114 func TestMarshalEscaping(t *testing.T) { |
|
115 msg := &Message{Body: &Generic{XMLName: xml.Name{Local: "body"}, |
|
116 Chardata: `&<!-- "`}} |
|
117 exp := `<message xmlns="jabber:client"><body>&<!-- "</body></message>` |
|
118 assertMarshal(t, exp, msg) |
|
119 } |
|
120 |
|
121 func TestUnmarshalMessage(t *testing.T) { |
|
122 str := `<message to="a@b.c"><body>foo!</body></message>` |
|
123 r := strings.NewReader(str) |
|
124 ch := make(chan interface{}) |
|
125 go readXml(r, ch, make(map[string]func(*xml.Name) interface{})) |
|
126 obs := <-ch |
|
127 exp := &Message{XMLName: xml.Name{Local: "message", Space: "jabber:client"}, |
|
128 Header: Header{To: "a@b.c", Innerxml: "<body>foo!</body>"}, |
|
129 Body: &Generic{XMLName: xml.Name{Local: "body", Space: "jabber:client"}, |
|
130 Chardata: "foo!"}} |
|
131 if !reflect.DeepEqual(obs, exp) { |
|
132 t.Errorf("read %s\ngot: %#v\nwant: %#v\n", str, obs, exp) |
|
133 } |
|
134 obsMsg, ok := obs.(*Message) |
|
135 if !ok { |
|
136 t.Fatalf("Not a Message: %T", obs) |
|
137 } |
|
138 obsBody := obsMsg.Body |
|
139 expBody := exp.Body |
|
140 if !reflect.DeepEqual(obsBody, expBody) { |
|
141 t.Errorf("body\ngot: %#v\nwant: %#v\n", obsBody, expBody) |
|
142 } |
|
143 } |