From d103ed6ca97ca5a2669f6cf5fe4b3d2a9c945f26 Mon Sep 17 00:00:00 2001 From: Christopher Speller Date: Wed, 17 May 2017 16:51:25 -0400 Subject: Upgrading server dependancies (#6431) --- vendor/gopkg.in/gomail.v2/message_test.go | 745 ++++++++++++++++++++++++++++++ 1 file changed, 745 insertions(+) create mode 100644 vendor/gopkg.in/gomail.v2/message_test.go (limited to 'vendor/gopkg.in/gomail.v2/message_test.go') diff --git a/vendor/gopkg.in/gomail.v2/message_test.go b/vendor/gopkg.in/gomail.v2/message_test.go new file mode 100644 index 000000000..acceff2a6 --- /dev/null +++ b/vendor/gopkg.in/gomail.v2/message_test.go @@ -0,0 +1,745 @@ +package gomail + +import ( + "bytes" + "encoding/base64" + "io" + "io/ioutil" + "path/filepath" + "regexp" + "strconv" + "strings" + "testing" + "time" +) + +func init() { + now = func() time.Time { + return time.Date(2014, 06, 25, 17, 46, 0, 0, time.UTC) + } +} + +type message struct { + from string + to []string + content string +} + +func TestMessage(t *testing.T) { + m := NewMessage() + m.SetAddressHeader("From", "from@example.com", "Señor From") + m.SetHeader("To", m.FormatAddress("to@example.com", "Señor To"), "tobis@example.com") + m.SetAddressHeader("Cc", "cc@example.com", "A, B") + m.SetAddressHeader("X-To", "ccbis@example.com", "à, b") + m.SetDateHeader("X-Date", now()) + m.SetHeader("X-Date-2", m.FormatDate(now())) + m.SetHeader("Subject", "¡Hola, señor!") + m.SetHeaders(map[string][]string{ + "X-Headers": {"Test", "Café"}, + }) + m.SetBody("text/plain", "¡Hola, señor!") + + want := &message{ + from: "from@example.com", + to: []string{ + "to@example.com", + "tobis@example.com", + "cc@example.com", + }, + content: "From: =?UTF-8?q?Se=C3=B1or_From?= \r\n" + + "To: =?UTF-8?q?Se=C3=B1or_To?= , tobis@example.com\r\n" + + "Cc: \"A, B\" \r\n" + + "X-To: =?UTF-8?b?w6AsIGI=?= \r\n" + + "X-Date: Wed, 25 Jun 2014 17:46:00 +0000\r\n" + + "X-Date-2: Wed, 25 Jun 2014 17:46:00 +0000\r\n" + + "X-Headers: Test, =?UTF-8?q?Caf=C3=A9?=\r\n" + + "Subject: =?UTF-8?q?=C2=A1Hola,_se=C3=B1or!?=\r\n" + + "Content-Type: text/plain; charset=UTF-8\r\n" + + "Content-Transfer-Encoding: quoted-printable\r\n" + + "\r\n" + + "=C2=A1Hola, se=C3=B1or!", + } + + testMessage(t, m, 0, want) +} + +func TestCustomMessage(t *testing.T) { + m := NewMessage(SetCharset("ISO-8859-1"), SetEncoding(Base64)) + m.SetHeaders(map[string][]string{ + "From": {"from@example.com"}, + "To": {"to@example.com"}, + "Subject": {"Café"}, + }) + m.SetBody("text/html", "¡Hola, señor!") + + want := &message{ + from: "from@example.com", + to: []string{"to@example.com"}, + content: "From: from@example.com\r\n" + + "To: to@example.com\r\n" + + "Subject: =?ISO-8859-1?b?Q2Fmw6k=?=\r\n" + + "Content-Type: text/html; charset=ISO-8859-1\r\n" + + "Content-Transfer-Encoding: base64\r\n" + + "\r\n" + + "wqFIb2xhLCBzZcOxb3Ih", + } + + testMessage(t, m, 0, want) +} + +func TestUnencodedMessage(t *testing.T) { + m := NewMessage(SetEncoding(Unencoded)) + m.SetHeaders(map[string][]string{ + "From": {"from@example.com"}, + "To": {"to@example.com"}, + "Subject": {"Café"}, + }) + m.SetBody("text/html", "¡Hola, señor!") + + want := &message{ + from: "from@example.com", + to: []string{"to@example.com"}, + content: "From: from@example.com\r\n" + + "To: to@example.com\r\n" + + "Subject: =?UTF-8?q?Caf=C3=A9?=\r\n" + + "Content-Type: text/html; charset=UTF-8\r\n" + + "Content-Transfer-Encoding: 8bit\r\n" + + "\r\n" + + "¡Hola, señor!", + } + + testMessage(t, m, 0, want) +} + +func TestRecipients(t *testing.T) { + m := NewMessage() + m.SetHeaders(map[string][]string{ + "From": {"from@example.com"}, + "To": {"to@example.com"}, + "Cc": {"cc@example.com"}, + "Bcc": {"bcc1@example.com", "bcc2@example.com"}, + "Subject": {"Hello!"}, + }) + m.SetBody("text/plain", "Test message") + + want := &message{ + from: "from@example.com", + to: []string{"to@example.com", "cc@example.com", "bcc1@example.com", "bcc2@example.com"}, + content: "From: from@example.com\r\n" + + "To: to@example.com\r\n" + + "Cc: cc@example.com\r\n" + + "Subject: Hello!\r\n" + + "Content-Type: text/plain; charset=UTF-8\r\n" + + "Content-Transfer-Encoding: quoted-printable\r\n" + + "\r\n" + + "Test message", + } + + testMessage(t, m, 0, want) +} + +func TestAlternative(t *testing.T) { + m := NewMessage() + m.SetHeader("From", "from@example.com") + m.SetHeader("To", "to@example.com") + m.SetBody("text/plain", "¡Hola, señor!") + m.AddAlternative("text/html", "¡Hola, señor!") + + want := &message{ + from: "from@example.com", + to: []string{"to@example.com"}, + content: "From: from@example.com\r\n" + + "To: to@example.com\r\n" + + "Content-Type: multipart/alternative;\r\n" + + " boundary=_BOUNDARY_1_\r\n" + + "\r\n" + + "--_BOUNDARY_1_\r\n" + + "Content-Type: text/plain; charset=UTF-8\r\n" + + "Content-Transfer-Encoding: quoted-printable\r\n" + + "\r\n" + + "=C2=A1Hola, se=C3=B1or!\r\n" + + "--_BOUNDARY_1_\r\n" + + "Content-Type: text/html; charset=UTF-8\r\n" + + "Content-Transfer-Encoding: quoted-printable\r\n" + + "\r\n" + + "=C2=A1Hola, se=C3=B1or!\r\n" + + "--_BOUNDARY_1_--\r\n", + } + + testMessage(t, m, 1, want) +} + +func TestPartSetting(t *testing.T) { + m := NewMessage() + m.SetHeader("From", "from@example.com") + m.SetHeader("To", "to@example.com") + m.SetBody("text/plain; format=flowed", "¡Hola, señor!", SetPartEncoding(Unencoded)) + m.AddAlternative("text/html", "¡Hola, señor!") + + want := &message{ + from: "from@example.com", + to: []string{"to@example.com"}, + content: "From: from@example.com\r\n" + + "To: to@example.com\r\n" + + "Content-Type: multipart/alternative;\r\n" + + " boundary=_BOUNDARY_1_\r\n" + + "\r\n" + + "--_BOUNDARY_1_\r\n" + + "Content-Type: text/plain; format=flowed; charset=UTF-8\r\n" + + "Content-Transfer-Encoding: 8bit\r\n" + + "\r\n" + + "¡Hola, señor!\r\n" + + "--_BOUNDARY_1_\r\n" + + "Content-Type: text/html; charset=UTF-8\r\n" + + "Content-Transfer-Encoding: quoted-printable\r\n" + + "\r\n" + + "=C2=A1Hola, se=C3=B1or!\r\n" + + "--_BOUNDARY_1_--\r\n", + } + + testMessage(t, m, 1, want) +} + +func TestBodyWriter(t *testing.T) { + m := NewMessage() + m.SetHeader("From", "from@example.com") + m.SetHeader("To", "to@example.com") + m.AddAlternativeWriter("text/plain", func(w io.Writer) error { + _, err := w.Write([]byte("Test message")) + return err + }) + m.AddAlternativeWriter("text/html", func(w io.Writer) error { + _, err := w.Write([]byte("Test HTML")) + return err + }) + + want := &message{ + from: "from@example.com", + to: []string{"to@example.com"}, + content: "From: from@example.com\r\n" + + "To: to@example.com\r\n" + + "Content-Type: multipart/alternative;\r\n" + + " boundary=_BOUNDARY_1_\r\n" + + "\r\n" + + "--_BOUNDARY_1_\r\n" + + "Content-Type: text/plain; charset=UTF-8\r\n" + + "Content-Transfer-Encoding: quoted-printable\r\n" + + "\r\n" + + "Test message\r\n" + + "--_BOUNDARY_1_\r\n" + + "Content-Type: text/html; charset=UTF-8\r\n" + + "Content-Transfer-Encoding: quoted-printable\r\n" + + "\r\n" + + "Test HTML\r\n" + + "--_BOUNDARY_1_--\r\n", + } + + testMessage(t, m, 1, want) +} + +func TestAttachmentOnly(t *testing.T) { + m := NewMessage() + m.SetHeader("From", "from@example.com") + m.SetHeader("To", "to@example.com") + m.Attach(mockCopyFile("/tmp/test.pdf")) + + want := &message{ + from: "from@example.com", + to: []string{"to@example.com"}, + content: "From: from@example.com\r\n" + + "To: to@example.com\r\n" + + "Content-Type: application/pdf; name=\"test.pdf\"\r\n" + + "Content-Disposition: attachment; filename=\"test.pdf\"\r\n" + + "Content-Transfer-Encoding: base64\r\n" + + "\r\n" + + base64.StdEncoding.EncodeToString([]byte("Content of test.pdf")), + } + + testMessage(t, m, 0, want) +} + +func TestAttachment(t *testing.T) { + m := NewMessage() + m.SetHeader("From", "from@example.com") + m.SetHeader("To", "to@example.com") + m.SetBody("text/plain", "Test") + m.Attach(mockCopyFile("/tmp/test.pdf")) + + want := &message{ + from: "from@example.com", + to: []string{"to@example.com"}, + content: "From: from@example.com\r\n" + + "To: to@example.com\r\n" + + "Content-Type: multipart/mixed;\r\n" + + " boundary=_BOUNDARY_1_\r\n" + + "\r\n" + + "--_BOUNDARY_1_\r\n" + + "Content-Type: text/plain; charset=UTF-8\r\n" + + "Content-Transfer-Encoding: quoted-printable\r\n" + + "\r\n" + + "Test\r\n" + + "--_BOUNDARY_1_\r\n" + + "Content-Type: application/pdf; name=\"test.pdf\"\r\n" + + "Content-Disposition: attachment; filename=\"test.pdf\"\r\n" + + "Content-Transfer-Encoding: base64\r\n" + + "\r\n" + + base64.StdEncoding.EncodeToString([]byte("Content of test.pdf")) + "\r\n" + + "--_BOUNDARY_1_--\r\n", + } + + testMessage(t, m, 1, want) +} + +func TestRename(t *testing.T) { + m := NewMessage() + m.SetHeader("From", "from@example.com") + m.SetHeader("To", "to@example.com") + m.SetBody("text/plain", "Test") + name, copy := mockCopyFile("/tmp/test.pdf") + rename := Rename("another.pdf") + m.Attach(name, copy, rename) + + want := &message{ + from: "from@example.com", + to: []string{"to@example.com"}, + content: "From: from@example.com\r\n" + + "To: to@example.com\r\n" + + "Content-Type: multipart/mixed;\r\n" + + " boundary=_BOUNDARY_1_\r\n" + + "\r\n" + + "--_BOUNDARY_1_\r\n" + + "Content-Type: text/plain; charset=UTF-8\r\n" + + "Content-Transfer-Encoding: quoted-printable\r\n" + + "\r\n" + + "Test\r\n" + + "--_BOUNDARY_1_\r\n" + + "Content-Type: application/pdf; name=\"another.pdf\"\r\n" + + "Content-Disposition: attachment; filename=\"another.pdf\"\r\n" + + "Content-Transfer-Encoding: base64\r\n" + + "\r\n" + + base64.StdEncoding.EncodeToString([]byte("Content of test.pdf")) + "\r\n" + + "--_BOUNDARY_1_--\r\n", + } + + testMessage(t, m, 1, want) +} + +func TestAttachmentsOnly(t *testing.T) { + m := NewMessage() + m.SetHeader("From", "from@example.com") + m.SetHeader("To", "to@example.com") + m.Attach(mockCopyFile("/tmp/test.pdf")) + m.Attach(mockCopyFile("/tmp/test.zip")) + + want := &message{ + from: "from@example.com", + to: []string{"to@example.com"}, + content: "From: from@example.com\r\n" + + "To: to@example.com\r\n" + + "Content-Type: multipart/mixed;\r\n" + + " boundary=_BOUNDARY_1_\r\n" + + "\r\n" + + "--_BOUNDARY_1_\r\n" + + "Content-Type: application/pdf; name=\"test.pdf\"\r\n" + + "Content-Disposition: attachment; filename=\"test.pdf\"\r\n" + + "Content-Transfer-Encoding: base64\r\n" + + "\r\n" + + base64.StdEncoding.EncodeToString([]byte("Content of test.pdf")) + "\r\n" + + "--_BOUNDARY_1_\r\n" + + "Content-Type: application/zip; name=\"test.zip\"\r\n" + + "Content-Disposition: attachment; filename=\"test.zip\"\r\n" + + "Content-Transfer-Encoding: base64\r\n" + + "\r\n" + + base64.StdEncoding.EncodeToString([]byte("Content of test.zip")) + "\r\n" + + "--_BOUNDARY_1_--\r\n", + } + + testMessage(t, m, 1, want) +} + +func TestAttachments(t *testing.T) { + m := NewMessage() + m.SetHeader("From", "from@example.com") + m.SetHeader("To", "to@example.com") + m.SetBody("text/plain", "Test") + m.Attach(mockCopyFile("/tmp/test.pdf")) + m.Attach(mockCopyFile("/tmp/test.zip")) + + want := &message{ + from: "from@example.com", + to: []string{"to@example.com"}, + content: "From: from@example.com\r\n" + + "To: to@example.com\r\n" + + "Content-Type: multipart/mixed;\r\n" + + " boundary=_BOUNDARY_1_\r\n" + + "\r\n" + + "--_BOUNDARY_1_\r\n" + + "Content-Type: text/plain; charset=UTF-8\r\n" + + "Content-Transfer-Encoding: quoted-printable\r\n" + + "\r\n" + + "Test\r\n" + + "--_BOUNDARY_1_\r\n" + + "Content-Type: application/pdf; name=\"test.pdf\"\r\n" + + "Content-Disposition: attachment; filename=\"test.pdf\"\r\n" + + "Content-Transfer-Encoding: base64\r\n" + + "\r\n" + + base64.StdEncoding.EncodeToString([]byte("Content of test.pdf")) + "\r\n" + + "--_BOUNDARY_1_\r\n" + + "Content-Type: application/zip; name=\"test.zip\"\r\n" + + "Content-Disposition: attachment; filename=\"test.zip\"\r\n" + + "Content-Transfer-Encoding: base64\r\n" + + "\r\n" + + base64.StdEncoding.EncodeToString([]byte("Content of test.zip")) + "\r\n" + + "--_BOUNDARY_1_--\r\n", + } + + testMessage(t, m, 1, want) +} + +func TestEmbedded(t *testing.T) { + m := NewMessage() + m.SetHeader("From", "from@example.com") + m.SetHeader("To", "to@example.com") + m.Embed(mockCopyFileWithHeader(m, "image1.jpg", map[string][]string{"Content-ID": {""}})) + m.Embed(mockCopyFile("image2.jpg")) + m.SetBody("text/plain", "Test") + + want := &message{ + from: "from@example.com", + to: []string{"to@example.com"}, + content: "From: from@example.com\r\n" + + "To: to@example.com\r\n" + + "Content-Type: multipart/related;\r\n" + + " boundary=_BOUNDARY_1_\r\n" + + "\r\n" + + "--_BOUNDARY_1_\r\n" + + "Content-Type: text/plain; charset=UTF-8\r\n" + + "Content-Transfer-Encoding: quoted-printable\r\n" + + "\r\n" + + "Test\r\n" + + "--_BOUNDARY_1_\r\n" + + "Content-Type: image/jpeg; name=\"image1.jpg\"\r\n" + + "Content-Disposition: inline; filename=\"image1.jpg\"\r\n" + + "Content-ID: \r\n" + + "Content-Transfer-Encoding: base64\r\n" + + "\r\n" + + base64.StdEncoding.EncodeToString([]byte("Content of image1.jpg")) + "\r\n" + + "--_BOUNDARY_1_\r\n" + + "Content-Type: image/jpeg; name=\"image2.jpg\"\r\n" + + "Content-Disposition: inline; filename=\"image2.jpg\"\r\n" + + "Content-ID: \r\n" + + "Content-Transfer-Encoding: base64\r\n" + + "\r\n" + + base64.StdEncoding.EncodeToString([]byte("Content of image2.jpg")) + "\r\n" + + "--_BOUNDARY_1_--\r\n", + } + + testMessage(t, m, 1, want) +} + +func TestFullMessage(t *testing.T) { + m := NewMessage() + m.SetHeader("From", "from@example.com") + m.SetHeader("To", "to@example.com") + m.SetBody("text/plain", "¡Hola, señor!") + m.AddAlternative("text/html", "¡Hola, señor!") + m.Attach(mockCopyFile("test.pdf")) + m.Embed(mockCopyFile("image.jpg")) + + want := &message{ + from: "from@example.com", + to: []string{"to@example.com"}, + content: "From: from@example.com\r\n" + + "To: to@example.com\r\n" + + "Content-Type: multipart/mixed;\r\n" + + " boundary=_BOUNDARY_1_\r\n" + + "\r\n" + + "--_BOUNDARY_1_\r\n" + + "Content-Type: multipart/related;\r\n" + + " boundary=_BOUNDARY_2_\r\n" + + "\r\n" + + "--_BOUNDARY_2_\r\n" + + "Content-Type: multipart/alternative;\r\n" + + " boundary=_BOUNDARY_3_\r\n" + + "\r\n" + + "--_BOUNDARY_3_\r\n" + + "Content-Type: text/plain; charset=UTF-8\r\n" + + "Content-Transfer-Encoding: quoted-printable\r\n" + + "\r\n" + + "=C2=A1Hola, se=C3=B1or!\r\n" + + "--_BOUNDARY_3_\r\n" + + "Content-Type: text/html; charset=UTF-8\r\n" + + "Content-Transfer-Encoding: quoted-printable\r\n" + + "\r\n" + + "=C2=A1Hola, se=C3=B1or!\r\n" + + "--_BOUNDARY_3_--\r\n" + + "\r\n" + + "--_BOUNDARY_2_\r\n" + + "Content-Type: image/jpeg; name=\"image.jpg\"\r\n" + + "Content-Disposition: inline; filename=\"image.jpg\"\r\n" + + "Content-ID: \r\n" + + "Content-Transfer-Encoding: base64\r\n" + + "\r\n" + + base64.StdEncoding.EncodeToString([]byte("Content of image.jpg")) + "\r\n" + + "--_BOUNDARY_2_--\r\n" + + "\r\n" + + "--_BOUNDARY_1_\r\n" + + "Content-Type: application/pdf; name=\"test.pdf\"\r\n" + + "Content-Disposition: attachment; filename=\"test.pdf\"\r\n" + + "Content-Transfer-Encoding: base64\r\n" + + "\r\n" + + base64.StdEncoding.EncodeToString([]byte("Content of test.pdf")) + "\r\n" + + "--_BOUNDARY_1_--\r\n", + } + + testMessage(t, m, 3, want) + + want = &message{ + from: "from@example.com", + to: []string{"to@example.com"}, + content: "From: from@example.com\r\n" + + "To: to@example.com\r\n" + + "Content-Type: text/plain; charset=UTF-8\r\n" + + "Content-Transfer-Encoding: quoted-printable\r\n" + + "\r\n" + + "Test reset", + } + m.Reset() + m.SetHeader("From", "from@example.com") + m.SetHeader("To", "to@example.com") + m.SetBody("text/plain", "Test reset") + testMessage(t, m, 0, want) +} + +func TestQpLineLength(t *testing.T) { + m := NewMessage() + m.SetHeader("From", "from@example.com") + m.SetHeader("To", "to@example.com") + m.SetBody("text/plain", + strings.Repeat("0", 76)+"\r\n"+ + strings.Repeat("0", 75)+"à\r\n"+ + strings.Repeat("0", 74)+"à\r\n"+ + strings.Repeat("0", 73)+"à\r\n"+ + strings.Repeat("0", 72)+"à\r\n"+ + strings.Repeat("0", 75)+"\r\n"+ + strings.Repeat("0", 76)+"\n") + + want := &message{ + from: "from@example.com", + to: []string{"to@example.com"}, + content: "From: from@example.com\r\n" + + "To: to@example.com\r\n" + + "Content-Type: text/plain; charset=UTF-8\r\n" + + "Content-Transfer-Encoding: quoted-printable\r\n" + + "\r\n" + + strings.Repeat("0", 75) + "=\r\n0\r\n" + + strings.Repeat("0", 75) + "=\r\n=C3=A0\r\n" + + strings.Repeat("0", 74) + "=\r\n=C3=A0\r\n" + + strings.Repeat("0", 73) + "=\r\n=C3=A0\r\n" + + strings.Repeat("0", 72) + "=C3=\r\n=A0\r\n" + + strings.Repeat("0", 75) + "\r\n" + + strings.Repeat("0", 75) + "=\r\n0\r\n", + } + + testMessage(t, m, 0, want) +} + +func TestBase64LineLength(t *testing.T) { + m := NewMessage(SetCharset("UTF-8"), SetEncoding(Base64)) + m.SetHeader("From", "from@example.com") + m.SetHeader("To", "to@example.com") + m.SetBody("text/plain", strings.Repeat("0", 58)) + + want := &message{ + from: "from@example.com", + to: []string{"to@example.com"}, + content: "From: from@example.com\r\n" + + "To: to@example.com\r\n" + + "Content-Type: text/plain; charset=UTF-8\r\n" + + "Content-Transfer-Encoding: base64\r\n" + + "\r\n" + + strings.Repeat("MDAw", 19) + "\r\nMA==", + } + + testMessage(t, m, 0, want) +} + +func TestEmptyName(t *testing.T) { + m := NewMessage() + m.SetAddressHeader("From", "from@example.com", "") + + want := &message{ + from: "from@example.com", + content: "From: from@example.com\r\n", + } + + testMessage(t, m, 0, want) +} + +func TestEmptyHeader(t *testing.T) { + m := NewMessage() + m.SetHeaders(map[string][]string{ + "From": {"from@example.com"}, + "X-Empty": nil, + }) + + want := &message{ + from: "from@example.com", + content: "From: from@example.com\r\n" + + "X-Empty:\r\n", + } + + testMessage(t, m, 0, want) +} + +func testMessage(t *testing.T, m *Message, bCount int, want *message) { + err := Send(stubSendMail(t, bCount, want), m) + if err != nil { + t.Error(err) + } +} + +func stubSendMail(t *testing.T, bCount int, want *message) SendFunc { + return func(from string, to []string, m io.WriterTo) error { + if from != want.from { + t.Fatalf("Invalid from, got %q, want %q", from, want.from) + } + + if len(to) != len(want.to) { + t.Fatalf("Invalid recipient count, \ngot %d: %q\nwant %d: %q", + len(to), to, + len(want.to), want.to, + ) + } + for i := range want.to { + if to[i] != want.to[i] { + t.Fatalf("Invalid recipient, got %q, want %q", + to[i], want.to[i], + ) + } + } + + buf := new(bytes.Buffer) + _, err := m.WriteTo(buf) + if err != nil { + t.Error(err) + } + got := buf.String() + wantMsg := string("Mime-Version: 1.0\r\n" + + "Date: Wed, 25 Jun 2014 17:46:00 +0000\r\n" + + want.content) + if bCount > 0 { + boundaries := getBoundaries(t, bCount, got) + for i, b := range boundaries { + wantMsg = strings.Replace(wantMsg, "_BOUNDARY_"+strconv.Itoa(i+1)+"_", b, -1) + } + } + + compareBodies(t, got, wantMsg) + + return nil + } +} + +func compareBodies(t *testing.T, got, want string) { + // We cannot do a simple comparison since the ordering of headers' fields + // is random. + gotLines := strings.Split(got, "\r\n") + wantLines := strings.Split(want, "\r\n") + + // We only test for too many lines, missing lines are tested after + if len(gotLines) > len(wantLines) { + t.Fatalf("Message has too many lines, \ngot %d:\n%s\nwant %d:\n%s", len(gotLines), got, len(wantLines), want) + } + + isInHeader := true + headerStart := 0 + for i, line := range wantLines { + if line == gotLines[i] { + if line == "" { + isInHeader = false + } else if !isInHeader && len(line) > 2 && line[:2] == "--" { + isInHeader = true + headerStart = i + 1 + } + continue + } + + if !isInHeader { + missingLine(t, line, got, want) + } + + isMissing := true + for j := headerStart; j < len(gotLines); j++ { + if gotLines[j] == "" { + break + } + if gotLines[j] == line { + isMissing = false + break + } + } + if isMissing { + missingLine(t, line, got, want) + } + } +} + +func missingLine(t *testing.T, line, got, want string) { + t.Fatalf("Missing line %q\ngot:\n%s\nwant:\n%s", line, got, want) +} + +func getBoundaries(t *testing.T, count int, m string) []string { + if matches := boundaryRegExp.FindAllStringSubmatch(m, count); matches != nil { + boundaries := make([]string, count) + for i, match := range matches { + boundaries[i] = match[1] + } + return boundaries + } + + t.Fatal("Boundary not found in body") + return []string{""} +} + +var boundaryRegExp = regexp.MustCompile("boundary=(\\w+)") + +func mockCopyFile(name string) (string, FileSetting) { + return name, SetCopyFunc(func(w io.Writer) error { + _, err := w.Write([]byte("Content of " + filepath.Base(name))) + return err + }) +} + +func mockCopyFileWithHeader(m *Message, name string, h map[string][]string) (string, FileSetting, FileSetting) { + name, f := mockCopyFile(name) + return name, f, SetHeader(h) +} + +func BenchmarkFull(b *testing.B) { + discardFunc := SendFunc(func(from string, to []string, m io.WriterTo) error { + _, err := m.WriteTo(ioutil.Discard) + return err + }) + + m := NewMessage() + b.ResetTimer() + for n := 0; n < b.N; n++ { + m.SetAddressHeader("From", "from@example.com", "Señor From") + m.SetHeaders(map[string][]string{ + "To": {"to@example.com"}, + "Cc": {"cc@example.com"}, + "Bcc": {"bcc1@example.com", "bcc2@example.com"}, + "Subject": {"¡Hola, señor!"}, + }) + m.SetBody("text/plain", "¡Hola, señor!") + m.AddAlternative("text/html", "

¡Hola, señor!

") + m.Attach(mockCopyFile("benchmark.txt")) + m.Embed(mockCopyFile("benchmark.jpg")) + + if err := Send(discardFunc, m); err != nil { + panic(err) + } + m.Reset() + } +} -- cgit v1.2.3-1-g7c22