github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/net/mail/message_test.go (about) 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 mail 6 7 import ( 8 "bytes" 9 "io/ioutil" 10 "reflect" 11 "testing" 12 "time" 13 ) 14 15 var 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> 23 To: Mary Smith <mary@example.net> 24 Subject: Saying Hello 25 Date: Fri, 21 Nov 1997 09:55:06 -0600 26 Message-ID: <1234@local.machine.example> 27 28 This is a message just to say hello. 29 So, "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 42 func 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 66 func 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 82 func 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 119 func 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 } 229 for _, test := range tests { 230 if len(test.exp) == 1 { 231 addr, err := ParseAddress(test.addrsStr) 232 if err != nil { 233 t.Errorf("Failed parsing (single) %q: %v", test.addrsStr, err) 234 continue 235 } 236 if !reflect.DeepEqual([]*Address{addr}, test.exp) { 237 t.Errorf("Parse (single) of %q: got %+v, want %+v", test.addrsStr, addr, test.exp) 238 } 239 } 240 241 addrs, err := ParseAddressList(test.addrsStr) 242 if err != nil { 243 t.Errorf("Failed parsing (list) %q: %v", test.addrsStr, err) 244 continue 245 } 246 if !reflect.DeepEqual(addrs, test.exp) { 247 t.Errorf("Parse (list) of %q: got %+v, want %+v", test.addrsStr, addrs, test.exp) 248 } 249 } 250 } 251 252 func TestAddressFormatting(t *testing.T) { 253 tests := []struct { 254 addr *Address 255 exp string 256 }{ 257 { 258 &Address{Address: "bob@example.com"}, 259 "<bob@example.com>", 260 }, 261 { 262 &Address{Name: "Bob", Address: "bob@example.com"}, 263 `"Bob" <bob@example.com>`, 264 }, 265 { 266 // note the ö (o with an umlaut) 267 &Address{Name: "Böb", Address: "bob@example.com"}, 268 `=?utf-8?q?B=C3=B6b?= <bob@example.com>`, 269 }, 270 } 271 for _, test := range tests { 272 s := test.addr.String() 273 if s != test.exp { 274 t.Errorf("Address%+v.String() = %v, want %v", *test.addr, s, test.exp) 275 } 276 } 277 }