<commit_before>// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package mail

import (
	"bytes"
	"io/ioutil"
	"reflect"
	"testing"
	"time"
)

var parseTests = []struct {
	in     string
	header Header
	body   string
}{
	{
		// RFC 5322, Appendix A.1.1
		in: `From: <NAME> <<EMAIL>>
To: <NAME> <<EMAIL>>
Subject: Saying Hello
Date: Fri, 21 Nov 1997 09:55:06 -0600
Message-ID: <<EMAIL>>

This is a message just to say hello.
So, "Hello".
`,
		header: Header{
			"From":       []string{"<NAME> <<EMAIL>>"},
			"To":         []string{"<NAME> <<EMAIL>>"},
			"Subject":    []string{"Saying Hello"},
			"Date":       []string{"Fri, 21 Nov 1997 09:55:06 -0600"},
			"Message-Id": []string{"<<EMAIL>>"},
		},
		body: "This is a message just to say hello.\nSo, \"Hello\".\n",
	},
}

func TestParsing(t *testing.T) {
	for i, test := range parseTests {
		msg, err := ReadMessage(bytes.NewBuffer([]byte(test.in)))
		if err != nil {
			t.Errorf("test #%d: Failed parsing message: %v", i, err)
			continue
		}
		if !headerEq(msg.Header, test.header) {
			t.Errorf("test #%d: Incorrectly parsed message header.\nGot:\n%+v\nWant:\n%+v",
				i, msg.Header, test.header)
		}
		body, err := ioutil.ReadAll(msg.Body)
		if err != nil {
			t.Errorf("test #%d: Failed reading body: %v", i, err)
			continue
		}
		bodyStr := string(body)
		if bodyStr != test.body {
			t.Errorf("test #%d: Incorrectly parsed message body.\nGot:\n%+v\nWant:\n%+v",
				i, bodyStr, test.body)
		}
	}
}

func headerEq(a, b Header) bool {
	if len(a) != len(b) {
		return false
	}
	for k, as := range a {
		bs, ok := b[k]
		if !ok {
			return false
		}
		if !reflect.DeepEqual(as, bs) {
			return false
		}
	}
	return true
}

func TestDateParsing(t *testing.T) {
	tests := []struct {
		dateStr string
		exp     time.Time
	}{
		// RFC 5322, Appendix A.1.1
		{
			"Fri, 21 Nov 1997 09:55:06 -0600",
			time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)),
		},
		// RFC5322, Appendix A.6.2
		// Obsolete date.
		{
			"21 Nov 97 09:55:06 GMT",
			time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("GMT", 0)),
		},
	}
	for _, test := range tests {
		hdr := Header{
			"Date": []string{test.dateStr},
		}
		date, err := hdr.Date()
		if err != nil {
			t.Errorf("Failed parsing %q: %v", test.dateStr, err)
			continue
		}
		if !reflect.DeepEqual(date, test.exp) {
			t.Errorf("Parse of %q: got %+v, want %+v", test.dateStr, date, test.exp)
		}
	}
}

func TestAddressParsing(t *testing.T) {
	tests := []struct {
		addrsStr string
		exp      []*Address
	}{
		// Bare address
		{
			`<EMAIL>`,
			[]*Address{{
				Address: "<EMAIL>",
			}},
		},
		// RFC 5322, Appendix A.1.1
		{
			`<NAME> <<EMAIL>>`,
			[]*Address{{
				Name:    "<NAME>",
				Address: "<EMAIL>",
			}},
		},
		// RFC 5322, Appendix A.1.2
		{
			`"<NAME>" <<EMAIL>>`,
			[]*Address{{
				Name:    "<NAME>",
				Address: "<EMAIL>",
			}},
		},
		{
			`<NAME> <<EMAIL>>, <EMAIL>, Who? <<EMAIL>>`,
			[]*Address{
				{
					Name:    "<NAME>",
					Address: "<EMAIL>",
				},
				{
					Address: "<EMAIL>",
				},
				{
					Name:    "Who?",
					Address: "<EMAIL>",
				},
			},
		},
		{
			`<<EMAIL>>, "Giant; \"Big\" Box" <<EMAIL>>`,
			[]*Address{
				{
					Address: "<EMAIL>",
				},
				{
					Name:    `Giant; "Big" Box`,
					Address: "<EMAIL>",
				},
			},
		},
		// RFC 5322, Appendix A.1.3
		// TODO(dsymonds): Group addresses.

		// RFC 2047 "Q"-encoded ISO-8859-1 address.
		{
			`=?iso-8859-1?q?J=F6rg_Doe?= <<EMAIL>>`,
			[]*Address{
				{
					Name:    `<NAME>`,
					Address: "<EMAIL>",
				},
			},
		},
		// RFC 2047 "Q"-encoded UTF-8 address.
		{
			`=?utf-8?q?J=C3=B6rg_Doe?= <<EMAIL>>`,
			[]*Address{
				{
					Name:    `<NAME>`,
					Address: "<EMAIL>",
				},
			},
		},
		// RFC 2047, Section 8.
		{
			`=?ISO-8859-1?Q?Andr=E9?= Pirard <<EMAIL>>`,
			[]*Address{
				{
					Name:    `<NAME>`,
					Address: "<EMAIL>",
				},
			},
		},
		// Custom example of RFC 2047 "B"-encoded ISO-8859-1 address.
		{
			`=?ISO-8859-1?B?SvZyZw==?= <<EMAIL>>`,
			[]*Address{
				{
					Name:    `Jörg`,
					Address: "<EMAIL>",
				},
			},
		},
		// Custom example of RFC 2047 "B"-encoded UTF-8 address.
		{
			`=?UTF-8?B?SsO2cmc=?= <<EMAIL>>`,
			[]*Address{
				{
					Name:    `Jörg`,
					Address: "<EMAIL>",
				},
			},
		},
	}
	for _, test := range tests {
		addrs, err := newAddrParser(test.addrsStr).parseAddressList()
		if err != nil {
			t.Errorf("Failed parsing %q: %v", test.addrsStr, err)
			continue
		}
		if !reflect.DeepEqual(addrs, test.exp) {
			t.Errorf("Parse of %q: got %+v, want %+v", test.addrsStr, addrs, test.exp)
		}
	}
}

func TestAddressFormatting(t *testing.T) {
	tests := []struct {
		addr *Address
		exp  string
	}{
		{
			&Address{Address: "<EMAIL>"},
			"<<EMAIL>>",
		},
		{
			&Address{Name: "Bob", Address: "<EMAIL>"},
			`"Bob" <<EMAIL>>`,
		},
		{
			// note the ö (o with an umlaut)
			&Address{Name: "Böb", Address: "<EMAIL>"},
			`=?utf-8?q?B=C3=B6b?= <<EMAIL>>`,
		},
	}
	for _, test := range tests {
		s := test.addr.String()
		if s != test.exp {
			t.Errorf("Address%+v.String() = %v, want %v", *test.addr, s, test.exp)
		}
	}
}
<commit_msg>net/mail: correctly compare parsed times in the test.<commit_after>// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package mail

import (
	"bytes"
	"io/ioutil"
	"reflect"
	"testing"
	"time"
)

var parseTests = []struct {
	in     string
	header Header
	body   string
}{
	{
		// RFC 5322, Appendix A.1.1
		in: `From: <NAME> <<EMAIL>>
To: <NAME> <<EMAIL>>
Subject: Saying Hello
Date: Fri, 21 Nov 1997 09:55:06 -0600
Message-ID: <<EMAIL>>

This is a message just to say hello.
So, "Hello".
`,
		header: Header{
			"From":       []string{"<NAME> <<EMAIL>>"},
			"To":         []string{"<NAME> <<EMAIL>>"},
			"Subject":    []string{"Saying Hello"},
			"Date":       []string{"Fri, 21 Nov 1997 09:55:06 -0600"},
			"Message-Id": []string{"<<EMAIL>>"},
		},
		body: "This is a message just to say hello.\nSo, \"Hello\".\n",
	},
}

func TestParsing(t *testing.T) {
	for i, test := range parseTests {
		msg, err := ReadMessage(bytes.NewBuffer([]byte(test.in)))
		if err != nil {
			t.Errorf("test #%d: Failed parsing message: %v", i, err)
			continue
		}
		if !headerEq(msg.Header, test.header) {
			t.Errorf("test #%d: Incorrectly parsed message header.\nGot:\n%+v\nWant:\n%+v",
				i, msg.Header, test.header)
		}
		body, err := ioutil.ReadAll(msg.Body)
		if err != nil {
			t.Errorf("test #%d: Failed reading body: %v", i, err)
			continue
		}
		bodyStr := string(body)
		if bodyStr != test.body {
			t.Errorf("test #%d: Incorrectly parsed message body.\nGot:\n%+v\nWant:\n%+v",
				i, bodyStr, test.body)
		}
	}
}

func headerEq(a, b Header) bool {
	if len(a) != len(b) {
		return false
	}
	for k, as := range a {
		bs, ok := b[k]
		if !ok {
			return false
		}
		if !reflect.DeepEqual(as, bs) {
			return false
		}
	}
	return true
}

func TestDateParsing(t *testing.T) {
	tests := []struct {
		dateStr string
		exp     time.Time
	}{
		// RFC 5322, Appendix A.1.1
		{
			"Fri, 21 Nov 1997 09:55:06 -0600",
			time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)),
		},
		// RFC5322, Appendix A.6.2
		// Obsolete date.
		{
			"21 Nov 97 09:55:06 GMT",
			time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("GMT", 0)),
		},
	}
	for _, test := range tests {
		hdr := Header{
			"Date": []string{test.dateStr},
		}
		date, err := hdr.Date()
		if err != nil {
			t.Errorf("Failed parsing %q: %v", test.dateStr, err)
			continue
		}
		if !date.Equal(test.exp) {
			t.Errorf("Parse of %q: got %+v, want %+v", test.dateStr, date, test.exp)
		}
	}
}

func TestAddressParsing(t *testing.T) {
	tests := []struct {
		addrsStr string
		exp      []*Address
	}{
		// Bare address
		{
			`<EMAIL>`,
			[]*Address{{
				Address: "<EMAIL>",
			}},
		},
		// RFC 5322, Appendix A.1.1
		{
			`<NAME> <<EMAIL>>`,
			[]*Address{{
				Name:    "<NAME>",
				Address: "<EMAIL>",
			}},
		},
		// RFC 5322, Appendix A.1.2
		{
			`"<NAME>" <<EMAIL>>`,
			[]*Address{{
				Name:    "<NAME>",
				Address: "<EMAIL>",
			}},
		},
		{
			`<NAME> <<EMAIL>>, <EMAIL>, Who? <<EMAIL>>`,
			[]*Address{
				{
					Name:    "<NAME>",
					Address: "<EMAIL>",
				},
				{
					Address: "<EMAIL>",
				},
				{
					Name:    "Who?",
					Address: "<EMAIL>",
				},
			},
		},
		{
			`<<EMAIL>>, "Giant; \"Big\" Box" <<EMAIL>>`,
			[]*Address{
				{
					Address: "<EMAIL>",
				},
				{
					Name:    `Giant; "Big" Box`,
					Address: "<EMAIL>",
				},
			},
		},
		// RFC 5322, Appendix A.1.3
		// TODO(dsymonds): Group addresses.

		// RFC 2047 "Q"-encoded ISO-8859-1 address.
		{
			`=?iso-8859-1?q?J=F6rg_Doe?= <<EMAIL>>`,
			[]*Address{
				{
					Name:    `<NAME>`,
					Address: "<EMAIL>",
				},
			},
		},
		// RFC 2047 "Q"-encoded UTF-8 address.
		{
			`=?utf-8?q?J=C3=B6rg_Doe?= <<EMAIL>>`,
			[]*Address{
				{
					Name:    `<NAME>`,
					Address: "<EMAIL>",
				},
			},
		},
		// RFC 2047, Section 8.
		{
			`=?ISO-8859-1?Q?Andr=E9?= Pirard <<EMAIL>>`,
			[]*Address{
				{
					Name:    `<NAME>`,
					Address: "<EMAIL>",
				},
			},
		},
		// Custom example of RFC 2047 "B"-encoded ISO-8859-1 address.
		{
			`=?ISO-8859-1?B?SvZyZw==?= <<EMAIL>>`,
			[]*Address{
				{
					Name:    `Jörg`,
					Address: "<EMAIL>",
				},
			},
		},
		// Custom example of RFC 2047 "B"-encoded UTF-8 address.
		{
			`=?UTF-8?B?SsO2cmc=?= <<EMAIL>>`,
			[]*Address{
				{
					Name:    `Jörg`,
					Address: "<EMAIL>",
				},
			},
		},
	}
	for _, test := range tests {
		addrs, err := newAddrParser(test.addrsStr).parseAddressList()
		if err != nil {
			t.Errorf("Failed parsing %q: %v", test.addrsStr, err)
			continue
		}
		if !reflect.DeepEqual(addrs, test.exp) {
			t.Errorf("Parse of %q: got %+v, want %+v", test.addrsStr, addrs, test.exp)
		}
	}
}

func TestAddressFormatting(t *testing.T) {
	tests := []struct {
		addr *Address
		exp  string
	}{
		{
			&Address{Address: "<EMAIL>"},
			"<<EMAIL>>",
		},
		{
			&Address{Name: "Bob", Address: "<EMAIL>"},
			`"Bob" <<EMAIL>>`,
		},
		{
			// note the ö (o with an umlaut)
			&Address{Name: "Böb", Address: "<EMAIL>"},
			`=?utf-8?q?B=C3=B6b?= <<EMAIL>>`,
		},
	}
	for _, test := range tests {
		s := test.addr.String()
		if s != test.exp {
			t.Errorf("Address%+v.String() = %v, want %v", *test.addr, s, test.exp)
		}
	}
}

{'fraction_non_alphanumeric': 0.2157478815576502, 'fraction_numerical': 0.03579929543939827, 'mean_word_length': 2.51892797319933, 'pattern_counts': {'":': 12, '<': 145, '<?xml version=': 0, '>': 145, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1189348', 'n_tokens_mistral': 5356, 'n_tokens_neox': 4321, 'n_words': 1004}