Initial commit
diff --git a/parsemail_test.go b/parsemail_test.go
new file mode 100644
index 0000000..402ff11
--- /dev/null
+++ b/parsemail_test.go
@@ -0,0 +1,330 @@
+package parsemail_test
+
+import (
+	"testing"
+	"github.com/DusanKasan/parsemail"
+	"strings"
+	"time"
+	"net/mail"
+	"encoding/base64"
+	"io/ioutil"
+)
+
+func TestParseEmail(t *testing.T) {
+	var testData = []struct{
+		mailData string
+
+		subject string
+		from []string
+		sender string
+		to []string
+		replyTo []string
+		cc []string
+		bcc []string
+		messageID string
+		inReplyTo []string
+		references []string
+		date time.Time
+		htmlBody string
+		textBody string
+		attachments []attachmentData
+		embeddedFiles []embeddedFileData
+		headerCheck func (mail.Header, *testing.T)
+	}{
+		{
+			mailData: Data1,
+			subject: "Test Subject 1",
+			from: []string{"Peter Paholík <peter.paholik@gmail.com>"},
+			to: []string{"dusan@kasan.sk"},
+			messageID: "CACtgX4kNXE7T5XKSKeH_zEcfUUmf2vXVASxYjaaK9cCn-3zb_g@mail.gmail.com",
+			date: parseDate("Fri, 07 Apr 2017 09:17:26 +0200"),
+			htmlBody: "<div dir=\"ltr\"><br></div>",
+			attachments: []attachmentData{
+				{
+					filename: "Peter Paholík 1 4 2017 2017-04-07.pdf",
+					base64data: "JVBERi0xLjQNCiW1tbW1DQoxIDAgb2JqDQo8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFIvTGFuZyhlbi1VUykgL1N0cnVjdFRyZWVSb290IDY3IDAgUi9NYXJrSW5mbzw8L01hcmtlZCB0cnVlPj4vT3V0cHV0SW50ZW50c1s8PC9UeXBlL091dHB1dEludGVudC9TL0dUU19QREZBMS9PdXRwdXRDb25kZXYgMzk1MzYyDQo+Pg0Kc3RhcnR4cmVmDQo0MTk4ODUNCiUlRU9GDQo=",
+				},
+			},
+		},
+		{
+			mailData: Data2,
+			subject: "Re: Test Subject 2",
+			from: []string{"Sender Man <sender@domain.com>"},
+			to: []string{"info@receiver.com"},
+			cc: []string{"Cc Man <ccman@gmail.com>"},
+			messageID: "0e9a21b4-01dc-e5c1-dcd6-58ce5aa61f4f@receiver.com",
+			inReplyTo: []string{"9ff38d03-c4ab-89b7-9328-e99d5e24e3ba@receiver.eu"},
+			references: []string{"2f6b7595-c01e-46e5-42bc-f263e1c4282d@receiver.com", "9ff38d03-c4ab-89b7-9328-e99d5e24e3ba@domain.com"},
+			date: parseDate("Fri, 07 Apr 2017 12:59:55 +0200"),
+			htmlBody: `<html>data<img src="part2.9599C449.04E5EC81@develhell.com"/></html>`,
+			textBody: `First level
+> Second level
+>> Third level
+>
+`,
+			embeddedFiles: []embeddedFileData{
+				{
+					cid: "part2.9599C449.04E5EC81@develhell.com",
+					base64data: "iVBORw0KGgoAAAANSUhEUgAAAQEAAAAYCAIAAAB1IN9NAAAACXBIWXMAAAsTAAALEwEAmpwYYKUKF+Os3baUndC0pDnwNAmLy1SUr2Gw0luxQuV/AwC6cEhVV5VRrwAAAABJRU5ErkJggg==",
+				},
+			},
+		},
+	}
+
+	for _, td := range testData {
+		e, err := parsemail.Parse(strings.NewReader(td.mailData))
+		if err != nil {
+			t.Error(err)
+		}
+
+		if td.subject != e.Subject() {
+			t.Errorf("Wrong subject. Expected: %s, Got: %s", td.subject, e.Subject())
+		}
+
+		if td.sender != e.Sender() {
+			t.Errorf("Wrong sender. Expected: %s, Got: %s", td.sender, e.Sender())
+		}
+
+		if !assertSliceEq(td.from, e.From()) {
+			t.Errorf("Wrong from. Expected: %s, Got: %s", td.from, e.From())
+		}
+
+		if !assertSliceEq(td.inReplyTo, e.InReplyTo()) {
+			t.Errorf("Wrong in reply to. Expected: %s, Got: %s", td.inReplyTo, e.InReplyTo())
+		}
+
+		if !assertSliceEq(td.references, e.References()) {
+			t.Errorf("Wrong references. Expected: %s, Got: %s", td.references, e.References())
+		}
+
+		if !assertSliceEq(td.to, e.To()) {
+			t.Errorf("Wrong to. Expected: %s, Got: %s", td.to, e.To())
+		}
+
+		if !assertSliceEq(td.replyTo, e.ReplyTo()) {
+			t.Errorf("Wrong reply to. Expected: %s, Got: %s", td.replyTo, e.ReplyTo())
+		}
+
+		if !assertSliceEq(td.cc, e.Cc()) {
+			t.Errorf("Wrong cc. Expected: %s, Got: %s", td.cc, e.Cc())
+		}
+
+		if !assertSliceEq(td.bcc, e.Bcc()) {
+			t.Errorf("Wrong cc. Expected: %s, Got: %s", td.cc, e.Cc())
+		}
+
+		date, err := e.Date()
+		if err != nil {
+			t.Error(err)
+		} else if td.date != date {
+			t.Errorf("Wrong date. Expected: %v, Got: %v", td.date, date)
+		}
+
+		if td.htmlBody != e.HTMLBody {
+			t.Errorf("Wrong html body. Expected: '%s', Got: '%s'", td.htmlBody, e.HTMLBody)
+		}
+
+		if td.textBody != e.TextBody {
+			t.Errorf("Wrong text body. Expected: '%s', Got: '%s'", td.textBody, e.TextBody)
+		}
+
+		if td.messageID != e.MessageID() {
+			t.Errorf("Wrong messageID. Expected: '%s', Got: '%s'", td.messageID, e.MessageID())
+		}
+
+		if len(td.attachments) != len(e.Attachments) {
+			t.Errorf("Incorrect number of attachments! Expected: %v, Got: %v.", len(td.attachments), len(e.Attachments))
+		} else {
+			attachs := e.Attachments[:]
+
+			for _, ad := range(td.attachments) {
+				found := false
+
+				for i, ra := range(attachs) {
+					b, err := ioutil.ReadAll(ra.Data)
+					if err != nil {
+						t.Error(err)
+					}
+
+					encoded := base64.StdEncoding.EncodeToString(b)
+					if ra.Filename == ad.filename && encoded == ad.base64data {
+						found = true
+						attachs = append(attachs[:i], attachs[i+1:]...)
+					}
+				}
+
+				if !found {
+					t.Errorf("Attachment not found: %s", ad.filename)
+				}
+			}
+
+			if len(attachs) != 0 {
+				t.Errorf("Email contains %v unexpected attachments: %v", len(attachs), attachs)
+			}
+		}
+
+		if len(td.embeddedFiles) != len(e.EmbeddedFiles) {
+			t.Errorf("Incorrect number of embedded files! Expected: %s, Got: %s.", len(td.embeddedFiles), len(e.EmbeddedFiles))
+		} else {
+			embeds := e.EmbeddedFiles[:]
+
+			for _, ad := range(td.embeddedFiles) {
+				found := false
+
+				for i, ra := range(embeds) {
+					b, err := ioutil.ReadAll(ra.Data)
+					if err != nil {
+						t.Error(err)
+					}
+
+					encoded := base64.StdEncoding.EncodeToString(b)
+
+					if ra.CID == ad.cid && encoded == ad.base64data {
+						found = true
+						embeds = append(embeds[:i], embeds[i+1:]...)
+					}
+				}
+
+				if !found {
+					t.Errorf("Embedded file not found: %s", ad.cid)
+				}
+			}
+
+			if len(embeds) != 0 {
+				t.Errorf("Email contains %v unexpected embedded files: %v", len(embeds), embeds)
+			}
+		}
+	}
+}
+
+func parseDate(in string) time.Time {
+	out, err := time.Parse(time.RFC1123Z, in)
+	if err != nil {
+		panic(err)
+	}
+
+	return out
+}
+
+type attachmentData struct{
+	filename string
+	base64data string
+}
+
+type embeddedFileData struct{
+	cid string
+	base64data string
+}
+
+func assertSliceEq(a, b []string) bool {
+	if len(a) == len(b) && len(a) == 0 {
+		return true
+	}
+
+	if a == nil && b == nil {
+		return true;
+	}
+
+	if a == nil || b == nil {
+		return false;
+	}
+
+	if len(a) != len(b) {
+		return false
+	}
+
+	for i := range a {
+		if a[i] != b[i] {
+			return false
+		}
+	}
+
+	return true
+}
+
+var Data1 = `From: =?UTF-8?Q?Peter_Pahol=C3=ADk?= <peter.paholik@gmail.com>
+Date: Fri, 7 Apr 2017 09:17:26 +0200
+Message-ID: <CACtgX4kNXE7T5XKSKeH_zEcfUUmf2vXVASxYjaaK9cCn-3zb_g@mail.gmail.com>
+Subject: Test Subject 1
+To: dusan@kasan.sk
+Content-Type: multipart/mixed; boundary=f403045f1dcc043a44054c8e6bbf
+
+--f403045f1dcc043a44054c8e6bbf
+Content-Type: multipart/alternative; boundary=f403045f1dcc043a3f054c8e6bbd
+
+--f403045f1dcc043a3f054c8e6bbd
+Content-Type: text/plain; charset=UTF-8
+
+
+
+--f403045f1dcc043a3f054c8e6bbd
+Content-Type: text/html; charset=UTF-8
+
+<div dir="ltr"><br></div>
+
+--f403045f1dcc043a3f054c8e6bbd--
+--f403045f1dcc043a44054c8e6bbf
+Content-Type: application/pdf;
+	name="=?UTF-8?Q?Peter_Paholi=CC=81k_1?=
+	=?UTF-8?Q?_4_2017_2017=2D04=2D07=2Epdf?="
+Content-Disposition: attachment;
+	filename="=?UTF-8?Q?Peter_Paholi=CC=81k_1?=
+	=?UTF-8?Q?_4_2017_2017=2D04=2D07=2Epdf?="
+Content-Transfer-Encoding: base64
+X-Attachment-Id: f_j17i0f0d0
+
+JVBERi0xLjQNCiW1tbW1DQoxIDAgb2JqDQo8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFIvTGFu
+Zyhlbi1VUykgL1N0cnVjdFRyZWVSb290IDY3IDAgUi9NYXJrSW5mbzw8L01hcmtlZCB0cnVlPj4v
+T3V0cHV0SW50ZW50c1s8PC9UeXBlL091dHB1dEludGVudC9TL0dUU19QREZBMS9PdXRwdXRDb25k
+ZXYgMzk1MzYyDQo+Pg0Kc3RhcnR4cmVmDQo0MTk4ODUNCiUlRU9GDQo=
+--f403045f1dcc043a44054c8e6bbf--
+`
+
+var Data2 = `Subject: Re: Test Subject 2
+To: info@receiver.com
+References: <2f6b7595-c01e-46e5-42bc-f263e1c4282d@receiver.com>
+ <9ff38d03-c4ab-89b7-9328-e99d5e24e3ba@domain.com>
+Cc: Cc Man <ccman@gmail.com>
+From: Sender Man <sender@domain.com>
+Message-ID: <0e9a21b4-01dc-e5c1-dcd6-58ce5aa61f4f@receiver.com>
+Date: Fri, 7 Apr 2017 12:59:55 +0200
+User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:45.0)
+ Gecko/20100101 Thunderbird/45.8.0
+MIME-Version: 1.0
+In-Reply-To: <9ff38d03-c4ab-89b7-9328-e99d5e24e3ba@receiver.eu>
+Content-Type: multipart/alternative;
+ boundary="------------C70C0458A558E585ACB75FB4"
+
+This is a multi-part message in MIME format.
+--------------C70C0458A558E585ACB75FB4
+Content-Type: text/plain; charset=utf-8; format=flowed
+Content-Transfer-Encoding: 8bit
+
+First level
+> Second level
+>> Third level
+>
+
+
+--------------C70C0458A558E585ACB75FB4
+Content-Type: multipart/related;
+ boundary="------------5DB4A1356834BB602A5F88B2"
+
+
+--------------5DB4A1356834BB602A5F88B2
+Content-Type: text/html; charset=utf-8
+Content-Transfer-Encoding: 8bit
+
+<html>data<img src="part2.9599C449.04E5EC81@develhell.com"/></html>
+
+--------------5DB4A1356834BB602A5F88B2
+Content-Type: image/png
+Content-Transfer-Encoding: base64
+Content-ID: <part2.9599C449.04E5EC81@develhell.com>
+
+iVBORw0KGgoAAAANSUhEUgAAAQEAAAAYCAIAAAB1IN9NAAAACXBIWXMAAAsTAAALEwEAmpwY
+YKUKF+Os3baUndC0pDnwNAmLy1SUr2Gw0luxQuV/AwC6cEhVV5VRrwAAAABJRU5ErkJggg==
+--------------5DB4A1356834BB602A5F88B2
+
+--------------C70C0458A558E585ACB75FB4--
+`
\ No newline at end of file