summaryrefslogtreecommitdiff
path: root/Lib/test/test_email/test_generator.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_email/test_generator.py')
-rw-r--r--Lib/test/test_email/test_generator.py199
1 files changed, 199 insertions, 0 deletions
diff --git a/Lib/test/test_email/test_generator.py b/Lib/test/test_email/test_generator.py
new file mode 100644
index 0000000000..8917408171
--- /dev/null
+++ b/Lib/test/test_email/test_generator.py
@@ -0,0 +1,199 @@
+import io
+import textwrap
+import unittest
+from email import message_from_string, message_from_bytes
+from email.generator import Generator, BytesGenerator
+from email import policy
+from test.test_email import TestEmailBase, parameterize
+
+
+@parameterize
+class TestGeneratorBase:
+
+ policy = policy.default
+
+ def msgmaker(self, msg, policy=None):
+ policy = self.policy if policy is None else policy
+ return self.msgfunc(msg, policy=policy)
+
+ refold_long_expected = {
+ 0: textwrap.dedent("""\
+ To: whom_it_may_concern@example.com
+ From: nobody_you_want_to_know@example.com
+ Subject: We the willing led by the unknowing are doing the
+ impossible for the ungrateful. We have done so much for so long with so little
+ we are now qualified to do anything with nothing.
+
+ None
+ """),
+ # From is wrapped because wrapped it fits in 40.
+ 40: textwrap.dedent("""\
+ To: whom_it_may_concern@example.com
+ From:
+ nobody_you_want_to_know@example.com
+ Subject: We the willing led by the
+ unknowing are doing the impossible for
+ the ungrateful. We have done so much
+ for so long with so little we are now
+ qualified to do anything with nothing.
+
+ None
+ """),
+ # Neither to nor from fit even if put on a new line,
+ # so we leave them sticking out on the first line.
+ 20: textwrap.dedent("""\
+ To: whom_it_may_concern@example.com
+ From: nobody_you_want_to_know@example.com
+ Subject: We the
+ willing led by the
+ unknowing are doing
+ the impossible for
+ the ungrateful. We
+ have done so much
+ for so long with so
+ little we are now
+ qualified to do
+ anything with
+ nothing.
+
+ None
+ """),
+ }
+ refold_long_expected[100] = refold_long_expected[0]
+
+ refold_all_expected = refold_long_expected.copy()
+ refold_all_expected[0] = (
+ "To: whom_it_may_concern@example.com\n"
+ "From: nobody_you_want_to_know@example.com\n"
+ "Subject: We the willing led by the unknowing are doing the "
+ "impossible for the ungrateful. We have done so much for "
+ "so long with so little we are now qualified to do anything "
+ "with nothing.\n"
+ "\n"
+ "None\n")
+ refold_all_expected[100] = (
+ "To: whom_it_may_concern@example.com\n"
+ "From: nobody_you_want_to_know@example.com\n"
+ "Subject: We the willing led by the unknowing are doing the "
+ "impossible for the ungrateful. We have\n"
+ " done so much for so long with so little we are now qualified "
+ "to do anything with nothing.\n"
+ "\n"
+ "None\n")
+
+ length_params = [n for n in refold_long_expected]
+
+ def length_as_maxheaderlen_parameter(self, n):
+ msg = self.msgmaker(self.typ(self.refold_long_expected[0]))
+ s = self.ioclass()
+ g = self.genclass(s, maxheaderlen=n, policy=self.policy)
+ g.flatten(msg)
+ self.assertEqual(s.getvalue(), self.typ(self.refold_long_expected[n]))
+
+ def length_as_max_line_length_policy(self, n):
+ msg = self.msgmaker(self.typ(self.refold_long_expected[0]))
+ s = self.ioclass()
+ g = self.genclass(s, policy=self.policy.clone(max_line_length=n))
+ g.flatten(msg)
+ self.assertEqual(s.getvalue(), self.typ(self.refold_long_expected[n]))
+
+ def length_as_maxheaderlen_parm_overrides_policy(self, n):
+ msg = self.msgmaker(self.typ(self.refold_long_expected[0]))
+ s = self.ioclass()
+ g = self.genclass(s, maxheaderlen=n,
+ policy=self.policy.clone(max_line_length=10))
+ g.flatten(msg)
+ self.assertEqual(s.getvalue(), self.typ(self.refold_long_expected[n]))
+
+ def length_as_max_line_length_with_refold_none_does_not_fold(self, n):
+ msg = self.msgmaker(self.typ(self.refold_long_expected[0]))
+ s = self.ioclass()
+ g = self.genclass(s, policy=self.policy.clone(refold_source='none',
+ max_line_length=n))
+ g.flatten(msg)
+ self.assertEqual(s.getvalue(), self.typ(self.refold_long_expected[0]))
+
+ def length_as_max_line_length_with_refold_all_folds(self, n):
+ msg = self.msgmaker(self.typ(self.refold_long_expected[0]))
+ s = self.ioclass()
+ g = self.genclass(s, policy=self.policy.clone(refold_source='all',
+ max_line_length=n))
+ g.flatten(msg)
+ self.assertEqual(s.getvalue(), self.typ(self.refold_all_expected[n]))
+
+ def test_crlf_control_via_policy(self):
+ source = "Subject: test\r\n\r\ntest body\r\n"
+ expected = source
+ msg = self.msgmaker(self.typ(source))
+ s = self.ioclass()
+ g = self.genclass(s, policy=policy.SMTP)
+ g.flatten(msg)
+ self.assertEqual(s.getvalue(), self.typ(expected))
+
+ def test_flatten_linesep_overrides_policy(self):
+ source = "Subject: test\n\ntest body\n"
+ expected = source
+ msg = self.msgmaker(self.typ(source))
+ s = self.ioclass()
+ g = self.genclass(s, policy=policy.SMTP)
+ g.flatten(msg, linesep='\n')
+ self.assertEqual(s.getvalue(), self.typ(expected))
+
+
+class TestGenerator(TestGeneratorBase, TestEmailBase):
+
+ msgfunc = staticmethod(message_from_string)
+ genclass = Generator
+ ioclass = io.StringIO
+ typ = str
+
+
+class TestBytesGenerator(TestGeneratorBase, TestEmailBase):
+
+ msgfunc = staticmethod(message_from_bytes)
+ genclass = BytesGenerator
+ ioclass = io.BytesIO
+ typ = lambda self, x: x.encode('ascii')
+
+ def test_cte_type_7bit_handles_unknown_8bit(self):
+ source = ("Subject: Maintenant je vous présente mon "
+ "collègue\n\n").encode('utf-8')
+ expected = ('Subject: Maintenant je vous =?unknown-8bit?q?'
+ 'pr=C3=A9sente_mon_coll=C3=A8gue?=\n\n').encode('ascii')
+ msg = message_from_bytes(source)
+ s = io.BytesIO()
+ g = BytesGenerator(s, policy=self.policy.clone(cte_type='7bit'))
+ g.flatten(msg)
+ self.assertEqual(s.getvalue(), expected)
+
+ def test_cte_type_7bit_transforms_8bit_cte(self):
+ source = textwrap.dedent("""\
+ From: foo@bar.com
+ To: Dinsdale
+ Subject: Nudge nudge, wink, wink
+ Mime-Version: 1.0
+ Content-Type: text/plain; charset="latin-1"
+ Content-Transfer-Encoding: 8bit
+
+ oh là là, know what I mean, know what I mean?
+ """).encode('latin1')
+ msg = message_from_bytes(source)
+ expected = textwrap.dedent("""\
+ From: foo@bar.com
+ To: Dinsdale
+ Subject: Nudge nudge, wink, wink
+ Mime-Version: 1.0
+ Content-Type: text/plain; charset="iso-8859-1"
+ Content-Transfer-Encoding: quoted-printable
+
+ oh l=E0 l=E0, know what I mean, know what I mean?
+ """).encode('ascii')
+ s = io.BytesIO()
+ g = BytesGenerator(s, policy=self.policy.clone(cte_type='7bit',
+ linesep='\n'))
+ g.flatten(msg)
+ self.assertEqual(s.getvalue(), expected)
+
+
+if __name__ == '__main__':
+ unittest.main()