PageRenderTime 211ms CodeModel.GetById 80ms app.highlight 20ms RepoModel.GetById 101ms app.codeStats 8ms

/libgo/go/net/mail/message_test.go

https://code.google.com/p/gofrontend/
Go | 295 lines | 265 code | 10 blank | 20 comment | 29 complexity | 7520cb25b1cbb703450091c97b926933 MD5 | raw file
  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
  5package mail
  6
  7import (
  8	"bytes"
  9	"io/ioutil"
 10	"reflect"
 11	"testing"
 12	"time"
 13)
 14
 15var parseTests = []struct {
 16	in     string
 17	header Header
 18	body   string
 19}{
 20	{
 21		// RFC 5322, Appendix A.1.1
 22		in: `From: John Doe <jdoe@machine.example>
 23To: Mary Smith <mary@example.net>
 24Subject: Saying Hello
 25Date: Fri, 21 Nov 1997 09:55:06 -0600
 26Message-ID: <1234@local.machine.example>
 27
 28This is a message just to say hello.
 29So, "Hello".
 30`,
 31		header: Header{
 32			"From":       []string{"John Doe <jdoe@machine.example>"},
 33			"To":         []string{"Mary Smith <mary@example.net>"},
 34			"Subject":    []string{"Saying Hello"},
 35			"Date":       []string{"Fri, 21 Nov 1997 09:55:06 -0600"},
 36			"Message-Id": []string{"<1234@local.machine.example>"},
 37		},
 38		body: "This is a message just to say hello.\nSo, \"Hello\".\n",
 39	},
 40}
 41
 42func TestParsing(t *testing.T) {
 43	for i, test := range parseTests {
 44		msg, err := ReadMessage(bytes.NewBuffer([]byte(test.in)))
 45		if err != nil {
 46			t.Errorf("test #%d: Failed parsing message: %v", i, err)
 47			continue
 48		}
 49		if !headerEq(msg.Header, test.header) {
 50			t.Errorf("test #%d: Incorrectly parsed message header.\nGot:\n%+v\nWant:\n%+v",
 51				i, msg.Header, test.header)
 52		}
 53		body, err := ioutil.ReadAll(msg.Body)
 54		if err != nil {
 55			t.Errorf("test #%d: Failed reading body: %v", i, err)
 56			continue
 57		}
 58		bodyStr := string(body)
 59		if bodyStr != test.body {
 60			t.Errorf("test #%d: Incorrectly parsed message body.\nGot:\n%+v\nWant:\n%+v",
 61				i, bodyStr, test.body)
 62		}
 63	}
 64}
 65
 66func headerEq(a, b Header) bool {
 67	if len(a) != len(b) {
 68		return false
 69	}
 70	for k, as := range a {
 71		bs, ok := b[k]
 72		if !ok {
 73			return false
 74		}
 75		if !reflect.DeepEqual(as, bs) {
 76			return false
 77		}
 78	}
 79	return true
 80}
 81
 82func TestDateParsing(t *testing.T) {
 83	tests := []struct {
 84		dateStr string
 85		exp     time.Time
 86	}{
 87		// RFC 5322, Appendix A.1.1
 88		{
 89			"Fri, 21 Nov 1997 09:55:06 -0600",
 90			time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)),
 91		},
 92		// RFC5322, Appendix A.6.2
 93		// Obsolete date.
 94		{
 95			"21 Nov 97 09:55:06 GMT",
 96			time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("GMT", 0)),
 97		},
 98		// Commonly found format not specified by RFC 5322.
 99		{
100			"Fri, 21 Nov 1997 09:55:06 -0600 (MDT)",
101			time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)),
102		},
103	}
104	for _, test := range tests {
105		hdr := Header{
106			"Date": []string{test.dateStr},
107		}
108		date, err := hdr.Date()
109		if err != nil {
110			t.Errorf("Failed parsing %q: %v", test.dateStr, err)
111			continue
112		}
113		if !date.Equal(test.exp) {
114			t.Errorf("Parse of %q: got %+v, want %+v", test.dateStr, date, test.exp)
115		}
116	}
117}
118
119func TestAddressParsing(t *testing.T) {
120	tests := []struct {
121		addrsStr string
122		exp      []*Address
123	}{
124		// Bare address
125		{
126			`jdoe@machine.example`,
127			[]*Address{{
128				Address: "jdoe@machine.example",
129			}},
130		},
131		// RFC 5322, Appendix A.1.1
132		{
133			`John Doe <jdoe@machine.example>`,
134			[]*Address{{
135				Name:    "John Doe",
136				Address: "jdoe@machine.example",
137			}},
138		},
139		// RFC 5322, Appendix A.1.2
140		{
141			`"Joe Q. Public" <john.q.public@example.com>`,
142			[]*Address{{
143				Name:    "Joe Q. Public",
144				Address: "john.q.public@example.com",
145			}},
146		},
147		{
148			`Mary Smith <mary@x.test>, jdoe@example.org, Who? <one@y.test>`,
149			[]*Address{
150				{
151					Name:    "Mary Smith",
152					Address: "mary@x.test",
153				},
154				{
155					Address: "jdoe@example.org",
156				},
157				{
158					Name:    "Who?",
159					Address: "one@y.test",
160				},
161			},
162		},
163		{
164			`<boss@nil.test>, "Giant; \"Big\" Box" <sysservices@example.net>`,
165			[]*Address{
166				{
167					Address: "boss@nil.test",
168				},
169				{
170					Name:    `Giant; "Big" Box`,
171					Address: "sysservices@example.net",
172				},
173			},
174		},
175		// RFC 5322, Appendix A.1.3
176		// TODO(dsymonds): Group addresses.
177
178		// RFC 2047 "Q"-encoded ISO-8859-1 address.
179		{
180			`=?iso-8859-1?q?J=F6rg_Doe?= <joerg@example.com>`,
181			[]*Address{
182				{
183					Name:    `Jörg Doe`,
184					Address: "joerg@example.com",
185				},
186			},
187		},
188		// RFC 2047 "Q"-encoded UTF-8 address.
189		{
190			`=?utf-8?q?J=C3=B6rg_Doe?= <joerg@example.com>`,
191			[]*Address{
192				{
193					Name:    `Jörg Doe`,
194					Address: "joerg@example.com",
195				},
196			},
197		},
198		// RFC 2047, Section 8.
199		{
200			`=?ISO-8859-1?Q?Andr=E9?= Pirard <PIRARD@vm1.ulg.ac.be>`,
201			[]*Address{
202				{
203					Name:    `André Pirard`,
204					Address: "PIRARD@vm1.ulg.ac.be",
205				},
206			},
207		},
208		// Custom example of RFC 2047 "B"-encoded ISO-8859-1 address.
209		{
210			`=?ISO-8859-1?B?SvZyZw==?= <joerg@example.com>`,
211			[]*Address{
212				{
213					Name:    `Jörg`,
214					Address: "joerg@example.com",
215				},
216			},
217		},
218		// Custom example of RFC 2047 "B"-encoded UTF-8 address.
219		{
220			`=?UTF-8?B?SsO2cmc=?= <joerg@example.com>`,
221			[]*Address{
222				{
223					Name:    `Jörg`,
224					Address: "joerg@example.com",
225				},
226			},
227		},
228		// Custom example with "." in name. For issue 4938
229		{
230			`Asem H. <noreply@example.com>`,
231			[]*Address{
232				{
233					Name:    `Asem H.`,
234					Address: "noreply@example.com",
235				},
236			},
237		},
238	}
239	for _, test := range tests {
240		if len(test.exp) == 1 {
241			addr, err := ParseAddress(test.addrsStr)
242			if err != nil {
243				t.Errorf("Failed parsing (single) %q: %v", test.addrsStr, err)
244				continue
245			}
246			if !reflect.DeepEqual([]*Address{addr}, test.exp) {
247				t.Errorf("Parse (single) of %q: got %+v, want %+v", test.addrsStr, addr, test.exp)
248			}
249		}
250
251		addrs, err := ParseAddressList(test.addrsStr)
252		if err != nil {
253			t.Errorf("Failed parsing (list) %q: %v", test.addrsStr, err)
254			continue
255		}
256		if !reflect.DeepEqual(addrs, test.exp) {
257			t.Errorf("Parse (list) of %q: got %+v, want %+v", test.addrsStr, addrs, test.exp)
258		}
259	}
260}
261
262func TestAddressFormatting(t *testing.T) {
263	tests := []struct {
264		addr *Address
265		exp  string
266	}{
267		{
268			&Address{Address: "bob@example.com"},
269			"<bob@example.com>",
270		},
271		{
272			&Address{Name: "Bob", Address: "bob@example.com"},
273			`"Bob" <bob@example.com>`,
274		},
275		{
276			// note the ö (o with an umlaut)
277			&Address{Name: "Böb", Address: "bob@example.com"},
278			`=?utf-8?q?B=C3=B6b?= <bob@example.com>`,
279		},
280		{
281			&Address{Name: "Bob Jane", Address: "bob@example.com"},
282			`"Bob Jane" <bob@example.com>`,
283		},
284		{
285			&Address{Name: "Böb Jacöb", Address: "bob@example.com"},
286			`=?utf-8?q?B=C3=B6b_Jac=C3=B6b?= <bob@example.com>`,
287		},
288	}
289	for _, test := range tests {
290		s := test.addr.String()
291		if s != test.exp {
292			t.Errorf("Address%+v.String() = %v, want %v", *test.addr, s, test.exp)
293		}
294	}
295}