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.
16 var parseTests
= []struct {
22 // RFC 5322, Appendix A.1.1
23 in
: `From: John Doe <jdoe@machine.example>
24 To: Mary Smith <mary@example.net>
26 Date: Fri, 21 Nov 1997 09:55:06 -0600
27 Message-ID: <1234@local.machine.example>
29 This is a message just to say hello.
33 "From": []string{"John Doe <jdoe@machine.example>"},
34 "To": []string{"Mary Smith <mary@example.net>"},
35 "Subject": []string{"Saying Hello"},
36 "Date": []string{"Fri, 21 Nov 1997 09:55:06 -0600"},
37 "Message-Id": []string{"<1234@local.machine.example>"},
39 body
: "This is a message just to say hello.\nSo, \"Hello\".\n",
43 func TestParsing(t
*testing
.T
) {
44 for i
, test
:= range parseTests
{
45 msg
, err
:= ReadMessage(bytes
.NewBuffer([]byte(test
.in
)))
47 t
.Errorf("test #%d: Failed parsing message: %v", i
, err
)
50 if !headerEq(msg
.Header
, test
.header
) {
51 t
.Errorf("test #%d: Incorrectly parsed message header.\nGot:\n%+v\nWant:\n%+v",
52 i
, msg
.Header
, test
.header
)
54 body
, err
:= ioutil
.ReadAll(msg
.Body
)
56 t
.Errorf("test #%d: Failed reading body: %v", i
, err
)
59 bodyStr
:= string(body
)
60 if bodyStr
!= test
.body
{
61 t
.Errorf("test #%d: Incorrectly parsed message body.\nGot:\n%+v\nWant:\n%+v",
62 i
, bodyStr
, test
.body
)
67 func headerEq(a
, b Header
) bool {
71 for k
, as
:= range a
{
76 if !reflect
.DeepEqual(as
, bs
) {
83 func TestDateParsing(t
*testing
.T
) {
88 // RFC 5322, Appendix A.1.1
90 "Fri, 21 Nov 1997 09:55:06 -0600",
91 time
.Date(1997, 11, 21, 9, 55, 6, 0, time
.FixedZone("", -6*60*60)),
93 // RFC5322, Appendix A.6.2
96 "21 Nov 97 09:55:06 GMT",
97 time
.Date(1997, 11, 21, 9, 55, 6, 0, time
.FixedZone("GMT", 0)),
99 // Commonly found format not specified by RFC 5322.
101 "Fri, 21 Nov 1997 09:55:06 -0600 (MDT)",
102 time
.Date(1997, 11, 21, 9, 55, 6, 0, time
.FixedZone("", -6*60*60)),
105 for _
, test
:= range tests
{
107 "Date": []string{test
.dateStr
},
109 date
, err
:= hdr
.Date()
111 t
.Errorf("Failed parsing %q: %v", test
.dateStr
, err
)
114 if !date
.Equal(test
.exp
) {
115 t
.Errorf("Parse of %q: got %+v, want %+v", test
.dateStr
, date
, test
.exp
)
120 func TestAddressParsingError(t
*testing
.T
) {
121 const txt
= "=?iso-8859-2?Q?Bogl=E1rka_Tak=E1cs?= <unknown@gmail.com>"
122 _
, err
:= ParseAddress(txt
)
123 if err
== nil ||
!strings
.Contains(err
.Error(), "charset not supported") {
124 t
.Errorf(`mail.ParseAddress(%q) err: %q, want ".*charset not supported.*"`, txt
, err
)
128 func TestAddressParsing(t
*testing
.T
) {
135 `jdoe@machine.example`,
137 Address
: "jdoe@machine.example",
140 // RFC 5322, Appendix A.1.1
142 `John Doe <jdoe@machine.example>`,
145 Address
: "jdoe@machine.example",
148 // RFC 5322, Appendix A.1.2
150 `"Joe Q. Public" <john.q.public@example.com>`,
152 Name
: "Joe Q. Public",
153 Address
: "john.q.public@example.com",
157 `Mary Smith <mary@x.test>, jdoe@example.org, Who? <one@y.test>`,
161 Address
: "mary@x.test",
164 Address
: "jdoe@example.org",
168 Address
: "one@y.test",
173 `<boss@nil.test>, "Giant; \"Big\" Box" <sysservices@example.net>`,
176 Address
: "boss@nil.test",
179 Name
: `Giant; "Big" Box`,
180 Address
: "sysservices@example.net",
184 // RFC 5322, Appendix A.1.3
185 // TODO(dsymonds): Group addresses.
187 // RFC 2047 "Q"-encoded ISO-8859-1 address.
189 `=?iso-8859-1?q?J=F6rg_Doe?= <joerg@example.com>`,
193 Address
: "joerg@example.com",
197 // RFC 2047 "Q"-encoded US-ASCII address. Dumb but legal.
199 `=?us-ascii?q?J=6Frg_Doe?= <joerg@example.com>`,
203 Address
: "joerg@example.com",
207 // RFC 2047 "Q"-encoded UTF-8 address.
209 `=?utf-8?q?J=C3=B6rg_Doe?= <joerg@example.com>`,
213 Address
: "joerg@example.com",
217 // RFC 2047, Section 8.
219 `=?ISO-8859-1?Q?Andr=E9?= Pirard <PIRARD@vm1.ulg.ac.be>`,
222 Name
: `André Pirard`,
223 Address
: "PIRARD@vm1.ulg.ac.be",
227 // Custom example of RFC 2047 "B"-encoded ISO-8859-1 address.
229 `=?ISO-8859-1?B?SvZyZw==?= <joerg@example.com>`,
233 Address
: "joerg@example.com",
237 // Custom example of RFC 2047 "B"-encoded UTF-8 address.
239 `=?UTF-8?B?SsO2cmc=?= <joerg@example.com>`,
243 Address
: "joerg@example.com",
247 // Custom example with "." in name. For issue 4938
249 `Asem H. <noreply@example.com>`,
253 Address
: "noreply@example.com",
258 for _
, test
:= range tests
{
259 if len(test
.exp
) == 1 {
260 addr
, err
:= ParseAddress(test
.addrsStr
)
262 t
.Errorf("Failed parsing (single) %q: %v", test
.addrsStr
, err
)
265 if !reflect
.DeepEqual([]*Address
{addr
}, test
.exp
) {
266 t
.Errorf("Parse (single) of %q: got %+v, want %+v", test
.addrsStr
, addr
, test
.exp
)
270 addrs
, err
:= ParseAddressList(test
.addrsStr
)
272 t
.Errorf("Failed parsing (list) %q: %v", test
.addrsStr
, err
)
275 if !reflect
.DeepEqual(addrs
, test
.exp
) {
276 t
.Errorf("Parse (list) of %q: got %+v, want %+v", test
.addrsStr
, addrs
, test
.exp
)
281 func TestAddressFormatting(t
*testing
.T
) {
287 &Address
{Address
: "bob@example.com"},
291 &Address
{Name
: "Bob", Address
: "bob@example.com"},
292 `"Bob" <bob@example.com>`,
295 // note the ö (o with an umlaut)
296 &Address
{Name
: "Böb", Address
: "bob@example.com"},
297 `=?utf-8?q?B=C3=B6b?= <bob@example.com>`,
300 &Address
{Name
: "Bob Jane", Address
: "bob@example.com"},
301 `"Bob Jane" <bob@example.com>`,
304 &Address
{Name
: "Böb Jacöb", Address
: "bob@example.com"},
305 `=?utf-8?q?B=C3=B6b_Jac=C3=B6b?= <bob@example.com>`,
308 for _
, test
:= range tests
{
309 s
:= test
.addr
.String()
311 t
.Errorf("Address%+v.String() = %v, want %v", *test
.addr
, s
, test
.exp
)