»Core Development>Code coverage>Lib/test/test_email/test__header_value_parser.py

Python code coverage for Lib/test/test_email/test__header_value_parser.py

#countcontent
1n/aimport string
2n/aimport unittest
3n/afrom email import _header_value_parser as parser
4n/afrom email import errors
5n/afrom email import policy
6n/afrom test.test_email import TestEmailBase, parameterize
7n/a
8n/aclass TestTokens(TestEmailBase):
9n/a
10n/a # EWWhiteSpaceTerminal
11n/a
12n/a def test_EWWhiteSpaceTerminal(self):
13n/a x = parser.EWWhiteSpaceTerminal(' \t', 'fws')
14n/a self.assertEqual(x, ' \t')
15n/a self.assertEqual(str(x), '')
16n/a self.assertEqual(x.value, '')
17n/a self.assertEqual(x.encoded, ' \t')
18n/a
19n/a # UnstructuredTokenList
20n/a
21n/a def test_undecodable_bytes_error_preserved(self):
22n/a badstr = b"le pouf c\xaflebre".decode('ascii', 'surrogateescape')
23n/a unst = parser.get_unstructured(badstr)
24n/a self.assertDefectsEqual(unst.all_defects, [errors.UndecodableBytesDefect])
25n/a parts = list(unst.parts)
26n/a self.assertDefectsEqual(parts[0].all_defects, [])
27n/a self.assertDefectsEqual(parts[1].all_defects, [])
28n/a self.assertDefectsEqual(parts[2].all_defects, [errors.UndecodableBytesDefect])
29n/a
30n/a
31n/aclass TestParserMixin:
32n/a
33n/a def _assert_results(self, tl, rest, string, value, defects, remainder,
34n/a comments=None):
35n/a self.assertEqual(str(tl), string)
36n/a self.assertEqual(tl.value, value)
37n/a self.assertDefectsEqual(tl.all_defects, defects)
38n/a self.assertEqual(rest, remainder)
39n/a if comments is not None:
40n/a self.assertEqual(tl.comments, comments)
41n/a
42n/a def _test_get_x(self, method, source, string, value, defects,
43n/a remainder, comments=None):
44n/a tl, rest = method(source)
45n/a self._assert_results(tl, rest, string, value, defects, remainder,
46n/a comments=None)
47n/a return tl
48n/a
49n/a def _test_parse_x(self, method, input, string, value, defects,
50n/a comments=None):
51n/a tl = method(input)
52n/a self._assert_results(tl, '', string, value, defects, '', comments)
53n/a return tl
54n/a
55n/a
56n/aclass TestParser(TestParserMixin, TestEmailBase):
57n/a
58n/a # _wsp_splitter
59n/a
60n/a rfc_printable_ascii = bytes(range(33, 127)).decode('ascii')
61n/a rfc_atext_chars = (string.ascii_letters + string.digits +
62n/a "!#$%&\'*+-/=?^_`{}|~")
63n/a rfc_dtext_chars = rfc_printable_ascii.translate(str.maketrans('','',r'\[]'))
64n/a
65n/a def test__wsp_splitter_one_word(self):
66n/a self.assertEqual(parser._wsp_splitter('foo', 1), ['foo'])
67n/a
68n/a def test__wsp_splitter_two_words(self):
69n/a self.assertEqual(parser._wsp_splitter('foo def', 1),
70n/a ['foo', ' ', 'def'])
71n/a
72n/a def test__wsp_splitter_ws_runs(self):
73n/a self.assertEqual(parser._wsp_splitter('foo \t def jik', 1),
74n/a ['foo', ' \t ', 'def jik'])
75n/a
76n/a
77n/a # get_fws
78n/a
79n/a def test_get_fws_only(self):
80n/a fws = self._test_get_x(parser.get_fws, ' \t ', ' \t ', ' ', [], '')
81n/a self.assertEqual(fws.token_type, 'fws')
82n/a
83n/a def test_get_fws_space(self):
84n/a self._test_get_x(parser.get_fws, ' foo', ' ', ' ', [], 'foo')
85n/a
86n/a def test_get_fws_ws_run(self):
87n/a self._test_get_x(parser.get_fws, ' \t foo ', ' \t ', ' ', [], 'foo ')
88n/a
89n/a # get_encoded_word
90n/a
91n/a def test_get_encoded_word_missing_start_raises(self):
92n/a with self.assertRaises(errors.HeaderParseError):
93n/a parser.get_encoded_word('abc')
94n/a
95n/a def test_get_encoded_word_missing_end_raises(self):
96n/a with self.assertRaises(errors.HeaderParseError):
97n/a parser.get_encoded_word('=?abc')
98n/a
99n/a def test_get_encoded_word_missing_middle_raises(self):
100n/a with self.assertRaises(errors.HeaderParseError):
101n/a parser.get_encoded_word('=?abc?=')
102n/a
103n/a def test_get_encoded_word_valid_ew(self):
104n/a self._test_get_x(parser.get_encoded_word,
105n/a '=?us-ascii?q?this_is_a_test?= bird',
106n/a 'this is a test',
107n/a 'this is a test',
108n/a [],
109n/a ' bird')
110n/a
111n/a def test_get_encoded_word_internal_spaces(self):
112n/a self._test_get_x(parser.get_encoded_word,
113n/a '=?us-ascii?q?this is a test?= bird',
114n/a 'this is a test',
115n/a 'this is a test',
116n/a [errors.InvalidHeaderDefect],
117n/a ' bird')
118n/a
119n/a def test_get_encoded_word_gets_first(self):
120n/a self._test_get_x(parser.get_encoded_word,
121n/a '=?us-ascii?q?first?= =?utf-8?q?second?=',
122n/a 'first',
123n/a 'first',
124n/a [],
125n/a ' =?utf-8?q?second?=')
126n/a
127n/a def test_get_encoded_word_gets_first_even_if_no_space(self):
128n/a self._test_get_x(parser.get_encoded_word,
129n/a '=?us-ascii?q?first?==?utf-8?q?second?=',
130n/a 'first',
131n/a 'first',
132n/a [],
133n/a '=?utf-8?q?second?=')
134n/a
135n/a def test_get_encoded_word_sets_extra_attributes(self):
136n/a ew = self._test_get_x(parser.get_encoded_word,
137n/a '=?us-ascii*jive?q?first_second?=',
138n/a 'first second',
139n/a 'first second',
140n/a [],
141n/a '')
142n/a self.assertEqual(ew.encoded, '=?us-ascii*jive?q?first_second?=')
143n/a self.assertEqual(ew.charset, 'us-ascii')
144n/a self.assertEqual(ew.lang, 'jive')
145n/a
146n/a def test_get_encoded_word_lang_default_is_blank(self):
147n/a ew = self._test_get_x(parser.get_encoded_word,
148n/a '=?us-ascii?q?first_second?=',
149n/a 'first second',
150n/a 'first second',
151n/a [],
152n/a '')
153n/a self.assertEqual(ew.encoded, '=?us-ascii?q?first_second?=')
154n/a self.assertEqual(ew.charset, 'us-ascii')
155n/a self.assertEqual(ew.lang, '')
156n/a
157n/a def test_get_encoded_word_non_printable_defect(self):
158n/a self._test_get_x(parser.get_encoded_word,
159n/a '=?us-ascii?q?first\x02second?=',
160n/a 'first\x02second',
161n/a 'first\x02second',
162n/a [errors.NonPrintableDefect],
163n/a '')
164n/a
165n/a def test_get_encoded_word_leading_internal_space(self):
166n/a self._test_get_x(parser.get_encoded_word,
167n/a '=?us-ascii?q?=20foo?=',
168n/a ' foo',
169n/a ' foo',
170n/a [],
171n/a '')
172n/a
173n/a def test_get_encoded_word_quopri_utf_escape_follows_cte(self):
174n/a # Issue 18044
175n/a self._test_get_x(parser.get_encoded_word,
176n/a '=?utf-8?q?=C3=89ric?=',
177n/a 'Éric',
178n/a 'Éric',
179n/a [],
180n/a '')
181n/a
182n/a # get_unstructured
183n/a
184n/a def _get_unst(self, value):
185n/a token = parser.get_unstructured(value)
186n/a return token, ''
187n/a
188n/a def test_get_unstructured_null(self):
189n/a self._test_get_x(self._get_unst, '', '', '', [], '')
190n/a
191n/a def test_get_unstructured_one_word(self):
192n/a self._test_get_x(self._get_unst, 'foo', 'foo', 'foo', [], '')
193n/a
194n/a def test_get_unstructured_normal_phrase(self):
195n/a self._test_get_x(self._get_unst, 'foo bar bird',
196n/a 'foo bar bird',
197n/a 'foo bar bird',
198n/a [],
199n/a '')
200n/a
201n/a def test_get_unstructured_normal_phrase_with_whitespace(self):
202n/a self._test_get_x(self._get_unst, 'foo \t bar bird',
203n/a 'foo \t bar bird',
204n/a 'foo bar bird',
205n/a [],
206n/a '')
207n/a
208n/a def test_get_unstructured_leading_whitespace(self):
209n/a self._test_get_x(self._get_unst, ' foo bar',
210n/a ' foo bar',
211n/a ' foo bar',
212n/a [],
213n/a '')
214n/a
215n/a def test_get_unstructured_trailing_whitespace(self):
216n/a self._test_get_x(self._get_unst, 'foo bar ',
217n/a 'foo bar ',
218n/a 'foo bar ',
219n/a [],
220n/a '')
221n/a
222n/a def test_get_unstructured_leading_and_trailing_whitespace(self):
223n/a self._test_get_x(self._get_unst, ' foo bar ',
224n/a ' foo bar ',
225n/a ' foo bar ',
226n/a [],
227n/a '')
228n/a
229n/a def test_get_unstructured_one_valid_ew_no_ws(self):
230n/a self._test_get_x(self._get_unst, '=?us-ascii?q?bar?=',
231n/a 'bar',
232n/a 'bar',
233n/a [],
234n/a '')
235n/a
236n/a def test_get_unstructured_one_ew_trailing_ws(self):
237n/a self._test_get_x(self._get_unst, '=?us-ascii?q?bar?= ',
238n/a 'bar ',
239n/a 'bar ',
240n/a [],
241n/a '')
242n/a
243n/a def test_get_unstructured_one_valid_ew_trailing_text(self):
244n/a self._test_get_x(self._get_unst, '=?us-ascii?q?bar?= bird',
245n/a 'bar bird',
246n/a 'bar bird',
247n/a [],
248n/a '')
249n/a
250n/a def test_get_unstructured_phrase_with_ew_in_middle_of_text(self):
251n/a self._test_get_x(self._get_unst, 'foo =?us-ascii?q?bar?= bird',
252n/a 'foo bar bird',
253n/a 'foo bar bird',
254n/a [],
255n/a '')
256n/a
257n/a def test_get_unstructured_phrase_with_two_ew(self):
258n/a self._test_get_x(self._get_unst,
259n/a 'foo =?us-ascii?q?bar?= =?us-ascii?q?bird?=',
260n/a 'foo barbird',
261n/a 'foo barbird',
262n/a [],
263n/a '')
264n/a
265n/a def test_get_unstructured_phrase_with_two_ew_trailing_ws(self):
266n/a self._test_get_x(self._get_unst,
267n/a 'foo =?us-ascii?q?bar?= =?us-ascii?q?bird?= ',
268n/a 'foo barbird ',
269n/a 'foo barbird ',
270n/a [],
271n/a '')
272n/a
273n/a def test_get_unstructured_phrase_with_ew_with_leading_ws(self):
274n/a self._test_get_x(self._get_unst,
275n/a ' =?us-ascii?q?bar?=',
276n/a ' bar',
277n/a ' bar',
278n/a [],
279n/a '')
280n/a
281n/a def test_get_unstructured_phrase_with_two_ew_extra_ws(self):
282n/a self._test_get_x(self._get_unst,
283n/a 'foo =?us-ascii?q?bar?= \t =?us-ascii?q?bird?=',
284n/a 'foo barbird',
285n/a 'foo barbird',
286n/a [],
287n/a '')
288n/a
289n/a def test_get_unstructured_two_ew_extra_ws_trailing_text(self):
290n/a self._test_get_x(self._get_unst,
291n/a '=?us-ascii?q?test?= =?us-ascii?q?foo?= val',
292n/a 'testfoo val',
293n/a 'testfoo val',
294n/a [],
295n/a '')
296n/a
297n/a def test_get_unstructured_ew_with_internal_ws(self):
298n/a self._test_get_x(self._get_unst,
299n/a '=?iso-8859-1?q?hello=20world?=',
300n/a 'hello world',
301n/a 'hello world',
302n/a [],
303n/a '')
304n/a
305n/a def test_get_unstructured_ew_with_internal_leading_ws(self):
306n/a self._test_get_x(self._get_unst,
307n/a ' =?us-ascii?q?=20test?= =?us-ascii?q?=20foo?= val',
308n/a ' test foo val',
309n/a ' test foo val',
310n/a [],
311n/a '')
312n/a
313n/a def test_get_unstructured_invaild_ew(self):
314n/a self._test_get_x(self._get_unst,
315n/a '=?test val',
316n/a '=?test val',
317n/a '=?test val',
318n/a [],
319n/a '')
320n/a
321n/a def test_get_unstructured_undecodable_bytes(self):
322n/a self._test_get_x(self._get_unst,
323n/a b'test \xACfoo val'.decode('ascii', 'surrogateescape'),
324n/a 'test \uDCACfoo val',
325n/a 'test \uDCACfoo val',
326n/a [errors.UndecodableBytesDefect],
327n/a '')
328n/a
329n/a def test_get_unstructured_undecodable_bytes_in_EW(self):
330n/a self._test_get_x(self._get_unst,
331n/a (b'=?us-ascii?q?=20test?= =?us-ascii?q?=20\xACfoo?='
332n/a b' val').decode('ascii', 'surrogateescape'),
333n/a ' test \uDCACfoo val',
334n/a ' test \uDCACfoo val',
335n/a [errors.UndecodableBytesDefect]*2,
336n/a '')
337n/a
338n/a def test_get_unstructured_missing_base64_padding(self):
339n/a self._test_get_x(self._get_unst,
340n/a '=?utf-8?b?dmk?=',
341n/a 'vi',
342n/a 'vi',
343n/a [errors.InvalidBase64PaddingDefect],
344n/a '')
345n/a
346n/a def test_get_unstructured_invalid_base64_character(self):
347n/a self._test_get_x(self._get_unst,
348n/a '=?utf-8?b?dm\x01k===?=',
349n/a 'vi',
350n/a 'vi',
351n/a [errors.InvalidBase64CharactersDefect],
352n/a '')
353n/a
354n/a def test_get_unstructured_invalid_base64_character_and_bad_padding(self):
355n/a self._test_get_x(self._get_unst,
356n/a '=?utf-8?b?dm\x01k?=',
357n/a 'vi',
358n/a 'vi',
359n/a [errors.InvalidBase64CharactersDefect,
360n/a errors.InvalidBase64PaddingDefect],
361n/a '')
362n/a
363n/a def test_get_unstructured_no_whitespace_between_ews(self):
364n/a self._test_get_x(self._get_unst,
365n/a '=?utf-8?q?foo?==?utf-8?q?bar?=',
366n/a 'foobar',
367n/a 'foobar',
368n/a [errors.InvalidHeaderDefect],
369n/a '')
370n/a
371n/a # get_qp_ctext
372n/a
373n/a def test_get_qp_ctext_only(self):
374n/a ptext = self._test_get_x(parser.get_qp_ctext,
375n/a 'foobar', 'foobar', ' ', [], '')
376n/a self.assertEqual(ptext.token_type, 'ptext')
377n/a
378n/a def test_get_qp_ctext_all_printables(self):
379n/a with_qp = self.rfc_printable_ascii.replace('\\', '\\\\')
380n/a with_qp = with_qp. replace('(', r'\(')
381n/a with_qp = with_qp.replace(')', r'\)')
382n/a ptext = self._test_get_x(parser.get_qp_ctext,
383n/a with_qp, self.rfc_printable_ascii, ' ', [], '')
384n/a
385n/a def test_get_qp_ctext_two_words_gets_first(self):
386n/a self._test_get_x(parser.get_qp_ctext,
387n/a 'foo de', 'foo', ' ', [], ' de')
388n/a
389n/a def test_get_qp_ctext_following_wsp_preserved(self):
390n/a self._test_get_x(parser.get_qp_ctext,
391n/a 'foo \t\tde', 'foo', ' ', [], ' \t\tde')
392n/a
393n/a def test_get_qp_ctext_up_to_close_paren_only(self):
394n/a self._test_get_x(parser.get_qp_ctext,
395n/a 'foo)', 'foo', ' ', [], ')')
396n/a
397n/a def test_get_qp_ctext_wsp_before_close_paren_preserved(self):
398n/a self._test_get_x(parser.get_qp_ctext,
399n/a 'foo )', 'foo', ' ', [], ' )')
400n/a
401n/a def test_get_qp_ctext_close_paren_mid_word(self):
402n/a self._test_get_x(parser.get_qp_ctext,
403n/a 'foo)bar', 'foo', ' ', [], ')bar')
404n/a
405n/a def test_get_qp_ctext_up_to_open_paren_only(self):
406n/a self._test_get_x(parser.get_qp_ctext,
407n/a 'foo(', 'foo', ' ', [], '(')
408n/a
409n/a def test_get_qp_ctext_wsp_before_open_paren_preserved(self):
410n/a self._test_get_x(parser.get_qp_ctext,
411n/a 'foo (', 'foo', ' ', [], ' (')
412n/a
413n/a def test_get_qp_ctext_open_paren_mid_word(self):
414n/a self._test_get_x(parser.get_qp_ctext,
415n/a 'foo(bar', 'foo', ' ', [], '(bar')
416n/a
417n/a def test_get_qp_ctext_non_printables(self):
418n/a ptext = self._test_get_x(parser.get_qp_ctext,
419n/a 'foo\x00bar)', 'foo\x00bar', ' ',
420n/a [errors.NonPrintableDefect], ')')
421n/a self.assertEqual(ptext.defects[0].non_printables[0], '\x00')
422n/a
423n/a # get_qcontent
424n/a
425n/a def test_get_qcontent_only(self):
426n/a ptext = self._test_get_x(parser.get_qcontent,
427n/a 'foobar', 'foobar', 'foobar', [], '')
428n/a self.assertEqual(ptext.token_type, 'ptext')
429n/a
430n/a def test_get_qcontent_all_printables(self):
431n/a with_qp = self.rfc_printable_ascii.replace('\\', '\\\\')
432n/a with_qp = with_qp. replace('"', r'\"')
433n/a ptext = self._test_get_x(parser.get_qcontent, with_qp,
434n/a self.rfc_printable_ascii,
435n/a self.rfc_printable_ascii, [], '')
436n/a
437n/a def test_get_qcontent_two_words_gets_first(self):
438n/a self._test_get_x(parser.get_qcontent,
439n/a 'foo de', 'foo', 'foo', [], ' de')
440n/a
441n/a def test_get_qcontent_following_wsp_preserved(self):
442n/a self._test_get_x(parser.get_qcontent,
443n/a 'foo \t\tde', 'foo', 'foo', [], ' \t\tde')
444n/a
445n/a def test_get_qcontent_up_to_dquote_only(self):
446n/a self._test_get_x(parser.get_qcontent,
447n/a 'foo"', 'foo', 'foo', [], '"')
448n/a
449n/a def test_get_qcontent_wsp_before_close_paren_preserved(self):
450n/a self._test_get_x(parser.get_qcontent,
451n/a 'foo "', 'foo', 'foo', [], ' "')
452n/a
453n/a def test_get_qcontent_close_paren_mid_word(self):
454n/a self._test_get_x(parser.get_qcontent,
455n/a 'foo"bar', 'foo', 'foo', [], '"bar')
456n/a
457n/a def test_get_qcontent_non_printables(self):
458n/a ptext = self._test_get_x(parser.get_qcontent,
459n/a 'foo\x00fg"', 'foo\x00fg', 'foo\x00fg',
460n/a [errors.NonPrintableDefect], '"')
461n/a self.assertEqual(ptext.defects[0].non_printables[0], '\x00')
462n/a
463n/a # get_atext
464n/a
465n/a def test_get_atext_only(self):
466n/a atext = self._test_get_x(parser.get_atext,
467n/a 'foobar', 'foobar', 'foobar', [], '')
468n/a self.assertEqual(atext.token_type, 'atext')
469n/a
470n/a def test_get_atext_all_atext(self):
471n/a atext = self._test_get_x(parser.get_atext, self.rfc_atext_chars,
472n/a self.rfc_atext_chars,
473n/a self.rfc_atext_chars, [], '')
474n/a
475n/a def test_get_atext_two_words_gets_first(self):
476n/a self._test_get_x(parser.get_atext,
477n/a 'foo bar', 'foo', 'foo', [], ' bar')
478n/a
479n/a def test_get_atext_following_wsp_preserved(self):
480n/a self._test_get_x(parser.get_atext,
481n/a 'foo \t\tbar', 'foo', 'foo', [], ' \t\tbar')
482n/a
483n/a def test_get_atext_up_to_special(self):
484n/a self._test_get_x(parser.get_atext,
485n/a 'foo@bar', 'foo', 'foo', [], '@bar')
486n/a
487n/a def test_get_atext_non_printables(self):
488n/a atext = self._test_get_x(parser.get_atext,
489n/a 'foo\x00bar(', 'foo\x00bar', 'foo\x00bar',
490n/a [errors.NonPrintableDefect], '(')
491n/a self.assertEqual(atext.defects[0].non_printables[0], '\x00')
492n/a
493n/a # get_bare_quoted_string
494n/a
495n/a def test_get_bare_quoted_string_only(self):
496n/a bqs = self._test_get_x(parser.get_bare_quoted_string,
497n/a '"foo"', '"foo"', 'foo', [], '')
498n/a self.assertEqual(bqs.token_type, 'bare-quoted-string')
499n/a
500n/a def test_get_bare_quoted_string_must_start_with_dquote(self):
501n/a with self.assertRaises(errors.HeaderParseError):
502n/a parser.get_bare_quoted_string('foo"')
503n/a with self.assertRaises(errors.HeaderParseError):
504n/a parser.get_bare_quoted_string(' "foo"')
505n/a
506n/a def test_get_bare_quoted_string_following_wsp_preserved(self):
507n/a self._test_get_x(parser.get_bare_quoted_string,
508n/a '"foo"\t bar', '"foo"', 'foo', [], '\t bar')
509n/a
510n/a def test_get_bare_quoted_string_multiple_words(self):
511n/a self._test_get_x(parser.get_bare_quoted_string,
512n/a '"foo bar moo"', '"foo bar moo"', 'foo bar moo', [], '')
513n/a
514n/a def test_get_bare_quoted_string_multiple_words_wsp_preserved(self):
515n/a self._test_get_x(parser.get_bare_quoted_string,
516n/a '" foo moo\t"', '" foo moo\t"', ' foo moo\t', [], '')
517n/a
518n/a def test_get_bare_quoted_string_end_dquote_mid_word(self):
519n/a self._test_get_x(parser.get_bare_quoted_string,
520n/a '"foo"bar', '"foo"', 'foo', [], 'bar')
521n/a
522n/a def test_get_bare_quoted_string_quoted_dquote(self):
523n/a self._test_get_x(parser.get_bare_quoted_string,
524n/a r'"foo\"in"a', r'"foo\"in"', 'foo"in', [], 'a')
525n/a
526n/a def test_get_bare_quoted_string_non_printables(self):
527n/a self._test_get_x(parser.get_bare_quoted_string,
528n/a '"a\x01a"', '"a\x01a"', 'a\x01a',
529n/a [errors.NonPrintableDefect], '')
530n/a
531n/a def test_get_bare_quoted_string_no_end_dquote(self):
532n/a self._test_get_x(parser.get_bare_quoted_string,
533n/a '"foo', '"foo"', 'foo',
534n/a [errors.InvalidHeaderDefect], '')
535n/a self._test_get_x(parser.get_bare_quoted_string,
536n/a '"foo ', '"foo "', 'foo ',
537n/a [errors.InvalidHeaderDefect], '')
538n/a
539n/a def test_get_bare_quoted_string_empty_quotes(self):
540n/a self._test_get_x(parser.get_bare_quoted_string,
541n/a '""', '""', '', [], '')
542n/a
543n/a # Issue 16983: apply postel's law to some bad encoding.
544n/a def test_encoded_word_inside_quotes(self):
545n/a self._test_get_x(parser.get_bare_quoted_string,
546n/a '"=?utf-8?Q?not_really_valid?="',
547n/a '"not really valid"',
548n/a 'not really valid',
549n/a [errors.InvalidHeaderDefect],
550n/a '')
551n/a
552n/a # get_comment
553n/a
554n/a def test_get_comment_only(self):
555n/a comment = self._test_get_x(parser.get_comment,
556n/a '(comment)', '(comment)', ' ', [], '', ['comment'])
557n/a self.assertEqual(comment.token_type, 'comment')
558n/a
559n/a def test_get_comment_must_start_with_paren(self):
560n/a with self.assertRaises(errors.HeaderParseError):
561n/a parser.get_comment('foo"')
562n/a with self.assertRaises(errors.HeaderParseError):
563n/a parser.get_comment(' (foo"')
564n/a
565n/a def test_get_comment_following_wsp_preserved(self):
566n/a self._test_get_x(parser.get_comment,
567n/a '(comment) \t', '(comment)', ' ', [], ' \t', ['comment'])
568n/a
569n/a def test_get_comment_multiple_words(self):
570n/a self._test_get_x(parser.get_comment,
571n/a '(foo bar) \t', '(foo bar)', ' ', [], ' \t', ['foo bar'])
572n/a
573n/a def test_get_comment_multiple_words_wsp_preserved(self):
574n/a self._test_get_x(parser.get_comment,
575n/a '( foo bar\t ) \t', '( foo bar\t )', ' ', [], ' \t',
576n/a [' foo bar\t '])
577n/a
578n/a def test_get_comment_end_paren_mid_word(self):
579n/a self._test_get_x(parser.get_comment,
580n/a '(foo)bar', '(foo)', ' ', [], 'bar', ['foo'])
581n/a
582n/a def test_get_comment_quoted_parens(self):
583n/a self._test_get_x(parser.get_comment,
584n/a r'(foo\) \(\)bar)', r'(foo\) \(\)bar)', ' ', [], '', ['foo) ()bar'])
585n/a
586n/a def test_get_comment_non_printable(self):
587n/a self._test_get_x(parser.get_comment,
588n/a '(foo\x7Fbar)', '(foo\x7Fbar)', ' ',
589n/a [errors.NonPrintableDefect], '', ['foo\x7Fbar'])
590n/a
591n/a def test_get_comment_no_end_paren(self):
592n/a self._test_get_x(parser.get_comment,
593n/a '(foo bar', '(foo bar)', ' ',
594n/a [errors.InvalidHeaderDefect], '', ['foo bar'])
595n/a self._test_get_x(parser.get_comment,
596n/a '(foo bar ', '(foo bar )', ' ',
597n/a [errors.InvalidHeaderDefect], '', ['foo bar '])
598n/a
599n/a def test_get_comment_nested_comment(self):
600n/a comment = self._test_get_x(parser.get_comment,
601n/a '(foo(bar))', '(foo(bar))', ' ', [], '', ['foo(bar)'])
602n/a self.assertEqual(comment[1].content, 'bar')
603n/a
604n/a def test_get_comment_nested_comment_wsp(self):
605n/a comment = self._test_get_x(parser.get_comment,
606n/a '(foo ( bar ) )', '(foo ( bar ) )', ' ', [], '', ['foo ( bar ) '])
607n/a self.assertEqual(comment[2].content, ' bar ')
608n/a
609n/a def test_get_comment_empty_comment(self):
610n/a self._test_get_x(parser.get_comment,
611n/a '()', '()', ' ', [], '', [''])
612n/a
613n/a def test_get_comment_multiple_nesting(self):
614n/a comment = self._test_get_x(parser.get_comment,
615n/a '(((((foo)))))', '(((((foo)))))', ' ', [], '', ['((((foo))))'])
616n/a for i in range(4, 0, -1):
617n/a self.assertEqual(comment[0].content, '('*(i-1)+'foo'+')'*(i-1))
618n/a comment = comment[0]
619n/a self.assertEqual(comment.content, 'foo')
620n/a
621n/a def test_get_comment_missing_end_of_nesting(self):
622n/a self._test_get_x(parser.get_comment,
623n/a '(((((foo)))', '(((((foo)))))', ' ',
624n/a [errors.InvalidHeaderDefect]*2, '', ['((((foo))))'])
625n/a
626n/a def test_get_comment_qs_in_nested_comment(self):
627n/a comment = self._test_get_x(parser.get_comment,
628n/a r'(foo (b\)))', r'(foo (b\)))', ' ', [], '', [r'foo (b\))'])
629n/a self.assertEqual(comment[2].content, 'b)')
630n/a
631n/a # get_cfws
632n/a
633n/a def test_get_cfws_only_ws(self):
634n/a cfws = self._test_get_x(parser.get_cfws,
635n/a ' \t \t', ' \t \t', ' ', [], '', [])
636n/a self.assertEqual(cfws.token_type, 'cfws')
637n/a
638n/a def test_get_cfws_only_comment(self):
639n/a cfws = self._test_get_x(parser.get_cfws,
640n/a '(foo)', '(foo)', ' ', [], '', ['foo'])
641n/a self.assertEqual(cfws[0].content, 'foo')
642n/a
643n/a def test_get_cfws_only_mixed(self):
644n/a cfws = self._test_get_x(parser.get_cfws,
645n/a ' (foo ) ( bar) ', ' (foo ) ( bar) ', ' ', [], '',
646n/a ['foo ', ' bar'])
647n/a self.assertEqual(cfws[1].content, 'foo ')
648n/a self.assertEqual(cfws[3].content, ' bar')
649n/a
650n/a def test_get_cfws_ends_at_non_leader(self):
651n/a cfws = self._test_get_x(parser.get_cfws,
652n/a '(foo) bar', '(foo) ', ' ', [], 'bar', ['foo'])
653n/a self.assertEqual(cfws[0].content, 'foo')
654n/a
655n/a def test_get_cfws_ends_at_non_printable(self):
656n/a cfws = self._test_get_x(parser.get_cfws,
657n/a '(foo) \x07', '(foo) ', ' ', [], '\x07', ['foo'])
658n/a self.assertEqual(cfws[0].content, 'foo')
659n/a
660n/a def test_get_cfws_non_printable_in_comment(self):
661n/a cfws = self._test_get_x(parser.get_cfws,
662n/a '(foo \x07) "test"', '(foo \x07) ', ' ',
663n/a [errors.NonPrintableDefect], '"test"', ['foo \x07'])
664n/a self.assertEqual(cfws[0].content, 'foo \x07')
665n/a
666n/a def test_get_cfws_header_ends_in_comment(self):
667n/a cfws = self._test_get_x(parser.get_cfws,
668n/a ' (foo ', ' (foo )', ' ',
669n/a [errors.InvalidHeaderDefect], '', ['foo '])
670n/a self.assertEqual(cfws[1].content, 'foo ')
671n/a
672n/a def test_get_cfws_multiple_nested_comments(self):
673n/a cfws = self._test_get_x(parser.get_cfws,
674n/a '(foo (bar)) ((a)(a))', '(foo (bar)) ((a)(a))', ' ', [],
675n/a '', ['foo (bar)', '(a)(a)'])
676n/a self.assertEqual(cfws[0].comments, ['foo (bar)'])
677n/a self.assertEqual(cfws[2].comments, ['(a)(a)'])
678n/a
679n/a # get_quoted_string
680n/a
681n/a def test_get_quoted_string_only(self):
682n/a qs = self._test_get_x(parser.get_quoted_string,
683n/a '"bob"', '"bob"', 'bob', [], '')
684n/a self.assertEqual(qs.token_type, 'quoted-string')
685n/a self.assertEqual(qs.quoted_value, '"bob"')
686n/a self.assertEqual(qs.content, 'bob')
687n/a
688n/a def test_get_quoted_string_with_wsp(self):
689n/a qs = self._test_get_x(parser.get_quoted_string,
690n/a '\t "bob" ', '\t "bob" ', ' bob ', [], '')
691n/a self.assertEqual(qs.quoted_value, ' "bob" ')
692n/a self.assertEqual(qs.content, 'bob')
693n/a
694n/a def test_get_quoted_string_with_comments_and_wsp(self):
695n/a qs = self._test_get_x(parser.get_quoted_string,
696n/a ' (foo) "bob"(bar)', ' (foo) "bob"(bar)', ' bob ', [], '')
697n/a self.assertEqual(qs[0][1].content, 'foo')
698n/a self.assertEqual(qs[2][0].content, 'bar')
699n/a self.assertEqual(qs.content, 'bob')
700n/a self.assertEqual(qs.quoted_value, ' "bob" ')
701n/a
702n/a def test_get_quoted_string_with_multiple_comments(self):
703n/a qs = self._test_get_x(parser.get_quoted_string,
704n/a ' (foo) (bar) "bob"(bird)', ' (foo) (bar) "bob"(bird)', ' bob ',
705n/a [], '')
706n/a self.assertEqual(qs[0].comments, ['foo', 'bar'])
707n/a self.assertEqual(qs[2].comments, ['bird'])
708n/a self.assertEqual(qs.content, 'bob')
709n/a self.assertEqual(qs.quoted_value, ' "bob" ')
710n/a
711n/a def test_get_quoted_string_non_printable_in_comment(self):
712n/a qs = self._test_get_x(parser.get_quoted_string,
713n/a ' (\x0A) "bob"', ' (\x0A) "bob"', ' bob',
714n/a [errors.NonPrintableDefect], '')
715n/a self.assertEqual(qs[0].comments, ['\x0A'])
716n/a self.assertEqual(qs.content, 'bob')
717n/a self.assertEqual(qs.quoted_value, ' "bob"')
718n/a
719n/a def test_get_quoted_string_non_printable_in_qcontent(self):
720n/a qs = self._test_get_x(parser.get_quoted_string,
721n/a ' (a) "a\x0B"', ' (a) "a\x0B"', ' a\x0B',
722n/a [errors.NonPrintableDefect], '')
723n/a self.assertEqual(qs[0].comments, ['a'])
724n/a self.assertEqual(qs.content, 'a\x0B')
725n/a self.assertEqual(qs.quoted_value, ' "a\x0B"')
726n/a
727n/a def test_get_quoted_string_internal_ws(self):
728n/a qs = self._test_get_x(parser.get_quoted_string,
729n/a ' (a) "foo bar "', ' (a) "foo bar "', ' foo bar ',
730n/a [], '')
731n/a self.assertEqual(qs[0].comments, ['a'])
732n/a self.assertEqual(qs.content, 'foo bar ')
733n/a self.assertEqual(qs.quoted_value, ' "foo bar "')
734n/a
735n/a def test_get_quoted_string_header_ends_in_comment(self):
736n/a qs = self._test_get_x(parser.get_quoted_string,
737n/a ' (a) "bob" (a', ' (a) "bob" (a)', ' bob ',
738n/a [errors.InvalidHeaderDefect], '')
739n/a self.assertEqual(qs[0].comments, ['a'])
740n/a self.assertEqual(qs[2].comments, ['a'])
741n/a self.assertEqual(qs.content, 'bob')
742n/a self.assertEqual(qs.quoted_value, ' "bob" ')
743n/a
744n/a def test_get_quoted_string_header_ends_in_qcontent(self):
745n/a qs = self._test_get_x(parser.get_quoted_string,
746n/a ' (a) "bob', ' (a) "bob"', ' bob',
747n/a [errors.InvalidHeaderDefect], '')
748n/a self.assertEqual(qs[0].comments, ['a'])
749n/a self.assertEqual(qs.content, 'bob')
750n/a self.assertEqual(qs.quoted_value, ' "bob"')
751n/a
752n/a def test_get_quoted_string_no_quoted_string(self):
753n/a with self.assertRaises(errors.HeaderParseError):
754n/a parser.get_quoted_string(' (ab) xyz')
755n/a
756n/a def test_get_quoted_string_qs_ends_at_noncfws(self):
757n/a qs = self._test_get_x(parser.get_quoted_string,
758n/a '\t "bob" fee', '\t "bob" ', ' bob ', [], 'fee')
759n/a self.assertEqual(qs.content, 'bob')
760n/a self.assertEqual(qs.quoted_value, ' "bob" ')
761n/a
762n/a # get_atom
763n/a
764n/a def test_get_atom_only(self):
765n/a atom = self._test_get_x(parser.get_atom,
766n/a 'bob', 'bob', 'bob', [], '')
767n/a self.assertEqual(atom.token_type, 'atom')
768n/a
769n/a def test_get_atom_with_wsp(self):
770n/a self._test_get_x(parser.get_atom,
771n/a '\t bob ', '\t bob ', ' bob ', [], '')
772n/a
773n/a def test_get_atom_with_comments_and_wsp(self):
774n/a atom = self._test_get_x(parser.get_atom,
775n/a ' (foo) bob(bar)', ' (foo) bob(bar)', ' bob ', [], '')
776n/a self.assertEqual(atom[0][1].content, 'foo')
777n/a self.assertEqual(atom[2][0].content, 'bar')
778n/a
779n/a def test_get_atom_with_multiple_comments(self):
780n/a atom = self._test_get_x(parser.get_atom,
781n/a ' (foo) (bar) bob(bird)', ' (foo) (bar) bob(bird)', ' bob ',
782n/a [], '')
783n/a self.assertEqual(atom[0].comments, ['foo', 'bar'])
784n/a self.assertEqual(atom[2].comments, ['bird'])
785n/a
786n/a def test_get_atom_non_printable_in_comment(self):
787n/a atom = self._test_get_x(parser.get_atom,
788n/a ' (\x0A) bob', ' (\x0A) bob', ' bob',
789n/a [errors.NonPrintableDefect], '')
790n/a self.assertEqual(atom[0].comments, ['\x0A'])
791n/a
792n/a def test_get_atom_non_printable_in_atext(self):
793n/a atom = self._test_get_x(parser.get_atom,
794n/a ' (a) a\x0B', ' (a) a\x0B', ' a\x0B',
795n/a [errors.NonPrintableDefect], '')
796n/a self.assertEqual(atom[0].comments, ['a'])
797n/a
798n/a def test_get_atom_header_ends_in_comment(self):
799n/a atom = self._test_get_x(parser.get_atom,
800n/a ' (a) bob (a', ' (a) bob (a)', ' bob ',
801n/a [errors.InvalidHeaderDefect], '')
802n/a self.assertEqual(atom[0].comments, ['a'])
803n/a self.assertEqual(atom[2].comments, ['a'])
804n/a
805n/a def test_get_atom_no_atom(self):
806n/a with self.assertRaises(errors.HeaderParseError):
807n/a parser.get_atom(' (ab) ')
808n/a
809n/a def test_get_atom_no_atom_before_special(self):
810n/a with self.assertRaises(errors.HeaderParseError):
811n/a parser.get_atom(' (ab) @')
812n/a
813n/a def test_get_atom_atom_ends_at_special(self):
814n/a atom = self._test_get_x(parser.get_atom,
815n/a ' (foo) bob(bar) @bang', ' (foo) bob(bar) ', ' bob ', [], '@bang')
816n/a self.assertEqual(atom[0].comments, ['foo'])
817n/a self.assertEqual(atom[2].comments, ['bar'])
818n/a
819n/a def test_get_atom_atom_ends_at_noncfws(self):
820n/a self._test_get_x(parser.get_atom,
821n/a 'bob fred', 'bob ', 'bob ', [], 'fred')
822n/a
823n/a def test_get_atom_rfc2047_atom(self):
824n/a self._test_get_x(parser.get_atom,
825n/a '=?utf-8?q?=20bob?=', ' bob', ' bob', [], '')
826n/a
827n/a # get_dot_atom_text
828n/a
829n/a def test_get_dot_atom_text(self):
830n/a dot_atom_text = self._test_get_x(parser.get_dot_atom_text,
831n/a 'foo.bar.bang', 'foo.bar.bang', 'foo.bar.bang', [], '')
832n/a self.assertEqual(dot_atom_text.token_type, 'dot-atom-text')
833n/a self.assertEqual(len(dot_atom_text), 5)
834n/a
835n/a def test_get_dot_atom_text_lone_atom_is_valid(self):
836n/a dot_atom_text = self._test_get_x(parser.get_dot_atom_text,
837n/a 'foo', 'foo', 'foo', [], '')
838n/a
839n/a def test_get_dot_atom_text_raises_on_leading_dot(self):
840n/a with self.assertRaises(errors.HeaderParseError):
841n/a parser.get_dot_atom_text('.foo.bar')
842n/a
843n/a def test_get_dot_atom_text_raises_on_trailing_dot(self):
844n/a with self.assertRaises(errors.HeaderParseError):
845n/a parser.get_dot_atom_text('foo.bar.')
846n/a
847n/a def test_get_dot_atom_text_raises_on_leading_non_atext(self):
848n/a with self.assertRaises(errors.HeaderParseError):
849n/a parser.get_dot_atom_text(' foo.bar')
850n/a with self.assertRaises(errors.HeaderParseError):
851n/a parser.get_dot_atom_text('@foo.bar')
852n/a with self.assertRaises(errors.HeaderParseError):
853n/a parser.get_dot_atom_text('"foo.bar"')
854n/a
855n/a def test_get_dot_atom_text_trailing_text_preserved(self):
856n/a dot_atom_text = self._test_get_x(parser.get_dot_atom_text,
857n/a 'foo@bar', 'foo', 'foo', [], '@bar')
858n/a
859n/a def test_get_dot_atom_text_trailing_ws_preserved(self):
860n/a dot_atom_text = self._test_get_x(parser.get_dot_atom_text,
861n/a 'foo .bar', 'foo', 'foo', [], ' .bar')
862n/a
863n/a # get_dot_atom
864n/a
865n/a def test_get_dot_atom_only(self):
866n/a dot_atom = self._test_get_x(parser.get_dot_atom,
867n/a 'foo.bar.bing', 'foo.bar.bing', 'foo.bar.bing', [], '')
868n/a self.assertEqual(dot_atom.token_type, 'dot-atom')
869n/a self.assertEqual(len(dot_atom), 1)
870n/a
871n/a def test_get_dot_atom_with_wsp(self):
872n/a self._test_get_x(parser.get_dot_atom,
873n/a '\t foo.bar.bing ', '\t foo.bar.bing ', ' foo.bar.bing ', [], '')
874n/a
875n/a def test_get_dot_atom_with_comments_and_wsp(self):
876n/a self._test_get_x(parser.get_dot_atom,
877n/a ' (sing) foo.bar.bing (here) ', ' (sing) foo.bar.bing (here) ',
878n/a ' foo.bar.bing ', [], '')
879n/a
880n/a def test_get_dot_atom_space_ends_dot_atom(self):
881n/a self._test_get_x(parser.get_dot_atom,
882n/a ' (sing) foo.bar .bing (here) ', ' (sing) foo.bar ',
883n/a ' foo.bar ', [], '.bing (here) ')
884n/a
885n/a def test_get_dot_atom_no_atom_raises(self):
886n/a with self.assertRaises(errors.HeaderParseError):
887n/a parser.get_dot_atom(' (foo) ')
888n/a
889n/a def test_get_dot_atom_leading_dot_raises(self):
890n/a with self.assertRaises(errors.HeaderParseError):
891n/a parser.get_dot_atom(' (foo) .bar')
892n/a
893n/a def test_get_dot_atom_two_dots_raises(self):
894n/a with self.assertRaises(errors.HeaderParseError):
895n/a parser.get_dot_atom('bar..bang')
896n/a
897n/a def test_get_dot_atom_trailing_dot_raises(self):
898n/a with self.assertRaises(errors.HeaderParseError):
899n/a parser.get_dot_atom(' (foo) bar.bang. foo')
900n/a
901n/a def test_get_dot_atom_rfc2047_atom(self):
902n/a self._test_get_x(parser.get_dot_atom,
903n/a '=?utf-8?q?=20bob?=', ' bob', ' bob', [], '')
904n/a
905n/a # get_word (if this were black box we'd repeat all the qs/atom tests)
906n/a
907n/a def test_get_word_atom_yields_atom(self):
908n/a word = self._test_get_x(parser.get_word,
909n/a ' (foo) bar (bang) :ah', ' (foo) bar (bang) ', ' bar ', [], ':ah')
910n/a self.assertEqual(word.token_type, 'atom')
911n/a self.assertEqual(word[0].token_type, 'cfws')
912n/a
913n/a def test_get_word_qs_yields_qs(self):
914n/a word = self._test_get_x(parser.get_word,
915n/a '"bar " (bang) ah', '"bar " (bang) ', 'bar ', [], 'ah')
916n/a self.assertEqual(word.token_type, 'quoted-string')
917n/a self.assertEqual(word[0].token_type, 'bare-quoted-string')
918n/a self.assertEqual(word[0].value, 'bar ')
919n/a self.assertEqual(word.content, 'bar ')
920n/a
921n/a def test_get_word_ends_at_dot(self):
922n/a self._test_get_x(parser.get_word,
923n/a 'foo.', 'foo', 'foo', [], '.')
924n/a
925n/a # get_phrase
926n/a
927n/a def test_get_phrase_simple(self):
928n/a phrase = self._test_get_x(parser.get_phrase,
929n/a '"Fred A. Johnson" is his name, oh.',
930n/a '"Fred A. Johnson" is his name',
931n/a 'Fred A. Johnson is his name',
932n/a [],
933n/a ', oh.')
934n/a self.assertEqual(phrase.token_type, 'phrase')
935n/a
936n/a def test_get_phrase_complex(self):
937n/a phrase = self._test_get_x(parser.get_phrase,
938n/a ' (A) bird (in (my|your)) "hand " is messy\t<>\t',
939n/a ' (A) bird (in (my|your)) "hand " is messy\t',
940n/a ' bird hand is messy ',
941n/a [],
942n/a '<>\t')
943n/a self.assertEqual(phrase[0][0].comments, ['A'])
944n/a self.assertEqual(phrase[0][2].comments, ['in (my|your)'])
945n/a
946n/a def test_get_phrase_obsolete(self):
947n/a phrase = self._test_get_x(parser.get_phrase,
948n/a 'Fred A.(weird).O Johnson',
949n/a 'Fred A.(weird).O Johnson',
950n/a 'Fred A. .O Johnson',
951n/a [errors.ObsoleteHeaderDefect]*3,
952n/a '')
953n/a self.assertEqual(len(phrase), 7)
954n/a self.assertEqual(phrase[3].comments, ['weird'])
955n/a
956n/a def test_get_phrase_pharse_must_start_with_word(self):
957n/a phrase = self._test_get_x(parser.get_phrase,
958n/a '(even weirder).name',
959n/a '(even weirder).name',
960n/a ' .name',
961n/a [errors.InvalidHeaderDefect] + [errors.ObsoleteHeaderDefect]*2,
962n/a '')
963n/a self.assertEqual(len(phrase), 3)
964n/a self.assertEqual(phrase[0].comments, ['even weirder'])
965n/a
966n/a def test_get_phrase_ending_with_obsolete(self):
967n/a phrase = self._test_get_x(parser.get_phrase,
968n/a 'simple phrase.(with trailing comment):boo',
969n/a 'simple phrase.(with trailing comment)',
970n/a 'simple phrase. ',
971n/a [errors.ObsoleteHeaderDefect]*2,
972n/a ':boo')
973n/a self.assertEqual(len(phrase), 4)
974n/a self.assertEqual(phrase[3].comments, ['with trailing comment'])
975n/a
976n/a def get_phrase_cfws_only_raises(self):
977n/a with self.assertRaises(errors.HeaderParseError):
978n/a parser.get_phrase(' (foo) ')
979n/a
980n/a # get_local_part
981n/a
982n/a def test_get_local_part_simple(self):
983n/a local_part = self._test_get_x(parser.get_local_part,
984n/a 'dinsdale@python.org', 'dinsdale', 'dinsdale', [], '@python.org')
985n/a self.assertEqual(local_part.token_type, 'local-part')
986n/a self.assertEqual(local_part.local_part, 'dinsdale')
987n/a
988n/a def test_get_local_part_with_dot(self):
989n/a local_part = self._test_get_x(parser.get_local_part,
990n/a 'Fred.A.Johnson@python.org',
991n/a 'Fred.A.Johnson',
992n/a 'Fred.A.Johnson',
993n/a [],
994n/a '@python.org')
995n/a self.assertEqual(local_part.local_part, 'Fred.A.Johnson')
996n/a
997n/a def test_get_local_part_with_whitespace(self):
998n/a local_part = self._test_get_x(parser.get_local_part,
999n/a ' Fred.A.Johnson @python.org',
1000n/a ' Fred.A.Johnson ',
1001n/a ' Fred.A.Johnson ',
1002n/a [],
1003n/a '@python.org')
1004n/a self.assertEqual(local_part.local_part, 'Fred.A.Johnson')
1005n/a
1006n/a def test_get_local_part_with_cfws(self):
1007n/a local_part = self._test_get_x(parser.get_local_part,
1008n/a ' (foo) Fred.A.Johnson (bar (bird)) @python.org',
1009n/a ' (foo) Fred.A.Johnson (bar (bird)) ',
1010n/a ' Fred.A.Johnson ',
1011n/a [],
1012n/a '@python.org')
1013n/a self.assertEqual(local_part.local_part, 'Fred.A.Johnson')
1014n/a self.assertEqual(local_part[0][0].comments, ['foo'])
1015n/a self.assertEqual(local_part[0][2].comments, ['bar (bird)'])
1016n/a
1017n/a def test_get_local_part_simple_quoted(self):
1018n/a local_part = self._test_get_x(parser.get_local_part,
1019n/a '"dinsdale"@python.org', '"dinsdale"', '"dinsdale"', [], '@python.org')
1020n/a self.assertEqual(local_part.token_type, 'local-part')
1021n/a self.assertEqual(local_part.local_part, 'dinsdale')
1022n/a
1023n/a def test_get_local_part_with_quoted_dot(self):
1024n/a local_part = self._test_get_x(parser.get_local_part,
1025n/a '"Fred.A.Johnson"@python.org',
1026n/a '"Fred.A.Johnson"',
1027n/a '"Fred.A.Johnson"',
1028n/a [],
1029n/a '@python.org')
1030n/a self.assertEqual(local_part.local_part, 'Fred.A.Johnson')
1031n/a
1032n/a def test_get_local_part_quoted_with_whitespace(self):
1033n/a local_part = self._test_get_x(parser.get_local_part,
1034n/a ' "Fred A. Johnson" @python.org',
1035n/a ' "Fred A. Johnson" ',
1036n/a ' "Fred A. Johnson" ',
1037n/a [],
1038n/a '@python.org')
1039n/a self.assertEqual(local_part.local_part, 'Fred A. Johnson')
1040n/a
1041n/a def test_get_local_part_quoted_with_cfws(self):
1042n/a local_part = self._test_get_x(parser.get_local_part,
1043n/a ' (foo) " Fred A. Johnson " (bar (bird)) @python.org',
1044n/a ' (foo) " Fred A. Johnson " (bar (bird)) ',
1045n/a ' " Fred A. Johnson " ',
1046n/a [],
1047n/a '@python.org')
1048n/a self.assertEqual(local_part.local_part, ' Fred A. Johnson ')
1049n/a self.assertEqual(local_part[0][0].comments, ['foo'])
1050n/a self.assertEqual(local_part[0][2].comments, ['bar (bird)'])
1051n/a
1052n/a
1053n/a def test_get_local_part_simple_obsolete(self):
1054n/a local_part = self._test_get_x(parser.get_local_part,
1055n/a 'Fred. A.Johnson@python.org',
1056n/a 'Fred. A.Johnson',
1057n/a 'Fred. A.Johnson',
1058n/a [errors.ObsoleteHeaderDefect],
1059n/a '@python.org')
1060n/a self.assertEqual(local_part.local_part, 'Fred.A.Johnson')
1061n/a
1062n/a def test_get_local_part_complex_obsolete_1(self):
1063n/a local_part = self._test_get_x(parser.get_local_part,
1064n/a ' (foo )Fred (bar).(bird) A.(sheep)Johnson."and dogs "@python.org',
1065n/a ' (foo )Fred (bar).(bird) A.(sheep)Johnson."and dogs "',
1066n/a ' Fred . A. Johnson.and dogs ',
1067n/a [errors.ObsoleteHeaderDefect],
1068n/a '@python.org')
1069n/a self.assertEqual(local_part.local_part, 'Fred.A.Johnson.and dogs ')
1070n/a
1071n/a def test_get_local_part_complex_obsolete_invalid(self):
1072n/a local_part = self._test_get_x(parser.get_local_part,
1073n/a ' (foo )Fred (bar).(bird) A.(sheep)Johnson "and dogs"@python.org',
1074n/a ' (foo )Fred (bar).(bird) A.(sheep)Johnson "and dogs"',
1075n/a ' Fred . A. Johnson and dogs',
1076n/a [errors.InvalidHeaderDefect]*2,
1077n/a '@python.org')
1078n/a self.assertEqual(local_part.local_part, 'Fred.A.Johnson and dogs')
1079n/a
1080n/a def test_get_local_part_no_part_raises(self):
1081n/a with self.assertRaises(errors.HeaderParseError):
1082n/a parser.get_local_part(' (foo) ')
1083n/a
1084n/a def test_get_local_part_special_instead_raises(self):
1085n/a with self.assertRaises(errors.HeaderParseError):
1086n/a parser.get_local_part(' (foo) @python.org')
1087n/a
1088n/a def test_get_local_part_trailing_dot(self):
1089n/a local_part = self._test_get_x(parser.get_local_part,
1090n/a ' borris.@python.org',
1091n/a ' borris.',
1092n/a ' borris.',
1093n/a [errors.InvalidHeaderDefect]*2,
1094n/a '@python.org')
1095n/a self.assertEqual(local_part.local_part, 'borris.')
1096n/a
1097n/a def test_get_local_part_trailing_dot_with_ws(self):
1098n/a local_part = self._test_get_x(parser.get_local_part,
1099n/a ' borris. @python.org',
1100n/a ' borris. ',
1101n/a ' borris. ',
1102n/a [errors.InvalidHeaderDefect]*2,
1103n/a '@python.org')
1104n/a self.assertEqual(local_part.local_part, 'borris.')
1105n/a
1106n/a def test_get_local_part_leading_dot(self):
1107n/a local_part = self._test_get_x(parser.get_local_part,
1108n/a '.borris@python.org',
1109n/a '.borris',
1110n/a '.borris',
1111n/a [errors.InvalidHeaderDefect]*2,
1112n/a '@python.org')
1113n/a self.assertEqual(local_part.local_part, '.borris')
1114n/a
1115n/a def test_get_local_part_leading_dot_after_ws(self):
1116n/a local_part = self._test_get_x(parser.get_local_part,
1117n/a ' .borris@python.org',
1118n/a ' .borris',
1119n/a ' .borris',
1120n/a [errors.InvalidHeaderDefect]*2,
1121n/a '@python.org')
1122n/a self.assertEqual(local_part.local_part, '.borris')
1123n/a
1124n/a def test_get_local_part_double_dot_raises(self):
1125n/a local_part = self._test_get_x(parser.get_local_part,
1126n/a ' borris.(foo).natasha@python.org',
1127n/a ' borris.(foo).natasha',
1128n/a ' borris. .natasha',
1129n/a [errors.InvalidHeaderDefect]*2,
1130n/a '@python.org')
1131n/a self.assertEqual(local_part.local_part, 'borris..natasha')
1132n/a
1133n/a def test_get_local_part_quoted_strings_in_atom_list(self):
1134n/a local_part = self._test_get_x(parser.get_local_part,
1135n/a '""example" example"@example.com',
1136n/a '""example" example"',
1137n/a 'example example',
1138n/a [errors.InvalidHeaderDefect]*3,
1139n/a '@example.com')
1140n/a self.assertEqual(local_part.local_part, 'example example')
1141n/a
1142n/a def test_get_local_part_valid_and_invalid_qp_in_atom_list(self):
1143n/a local_part = self._test_get_x(parser.get_local_part,
1144n/a r'"\\"example\\" example"@example.com',
1145n/a r'"\\"example\\" example"',
1146n/a r'\example\\ example',
1147n/a [errors.InvalidHeaderDefect]*5,
1148n/a '@example.com')
1149n/a self.assertEqual(local_part.local_part, r'\example\\ example')
1150n/a
1151n/a def test_get_local_part_unicode_defect(self):
1152n/a # Currently this only happens when parsing unicode, not when parsing
1153n/a # stuff that was originally binary.
1154n/a local_part = self._test_get_x(parser.get_local_part,
1155n/a 'exámple@example.com',
1156n/a 'exámple',
1157n/a 'exámple',
1158n/a [errors.NonASCIILocalPartDefect],
1159n/a '@example.com')
1160n/a self.assertEqual(local_part.local_part, 'exámple')
1161n/a
1162n/a # get_dtext
1163n/a
1164n/a def test_get_dtext_only(self):
1165n/a dtext = self._test_get_x(parser.get_dtext,
1166n/a 'foobar', 'foobar', 'foobar', [], '')
1167n/a self.assertEqual(dtext.token_type, 'ptext')
1168n/a
1169n/a def test_get_dtext_all_dtext(self):
1170n/a dtext = self._test_get_x(parser.get_dtext, self.rfc_dtext_chars,
1171n/a self.rfc_dtext_chars,
1172n/a self.rfc_dtext_chars, [], '')
1173n/a
1174n/a def test_get_dtext_two_words_gets_first(self):
1175n/a self._test_get_x(parser.get_dtext,
1176n/a 'foo bar', 'foo', 'foo', [], ' bar')
1177n/a
1178n/a def test_get_dtext_following_wsp_preserved(self):
1179n/a self._test_get_x(parser.get_dtext,
1180n/a 'foo \t\tbar', 'foo', 'foo', [], ' \t\tbar')
1181n/a
1182n/a def test_get_dtext_non_printables(self):
1183n/a dtext = self._test_get_x(parser.get_dtext,
1184n/a 'foo\x00bar]', 'foo\x00bar', 'foo\x00bar',
1185n/a [errors.NonPrintableDefect], ']')
1186n/a self.assertEqual(dtext.defects[0].non_printables[0], '\x00')
1187n/a
1188n/a def test_get_dtext_with_qp(self):
1189n/a ptext = self._test_get_x(parser.get_dtext,
1190n/a r'foo\]\[\\bar\b\e\l\l',
1191n/a r'foo][\barbell',
1192n/a r'foo][\barbell',
1193n/a [errors.ObsoleteHeaderDefect],
1194n/a '')
1195n/a
1196n/a def test_get_dtext_up_to_close_bracket_only(self):
1197n/a self._test_get_x(parser.get_dtext,
1198n/a 'foo]', 'foo', 'foo', [], ']')
1199n/a
1200n/a def test_get_dtext_wsp_before_close_bracket_preserved(self):
1201n/a self._test_get_x(parser.get_dtext,
1202n/a 'foo ]', 'foo', 'foo', [], ' ]')
1203n/a
1204n/a def test_get_dtext_close_bracket_mid_word(self):
1205n/a self._test_get_x(parser.get_dtext,
1206n/a 'foo]bar', 'foo', 'foo', [], ']bar')
1207n/a
1208n/a def test_get_dtext_up_to_open_bracket_only(self):
1209n/a self._test_get_x(parser.get_dtext,
1210n/a 'foo[', 'foo', 'foo', [], '[')
1211n/a
1212n/a def test_get_dtext_wsp_before_open_bracket_preserved(self):
1213n/a self._test_get_x(parser.get_dtext,
1214n/a 'foo [', 'foo', 'foo', [], ' [')
1215n/a
1216n/a def test_get_dtext_open_bracket_mid_word(self):
1217n/a self._test_get_x(parser.get_dtext,
1218n/a 'foo[bar', 'foo', 'foo', [], '[bar')
1219n/a
1220n/a # get_domain_literal
1221n/a
1222n/a def test_get_domain_literal_only(self):
1223n/a domain_literal = domain_literal = self._test_get_x(parser.get_domain_literal,
1224n/a '[127.0.0.1]',
1225n/a '[127.0.0.1]',
1226n/a '[127.0.0.1]',
1227n/a [],
1228n/a '')
1229n/a self.assertEqual(domain_literal.token_type, 'domain-literal')
1230n/a self.assertEqual(domain_literal.domain, '[127.0.0.1]')
1231n/a self.assertEqual(domain_literal.ip, '127.0.0.1')
1232n/a
1233n/a def test_get_domain_literal_with_internal_ws(self):
1234n/a domain_literal = self._test_get_x(parser.get_domain_literal,
1235n/a '[ 127.0.0.1\t ]',
1236n/a '[ 127.0.0.1\t ]',
1237n/a '[ 127.0.0.1 ]',
1238n/a [],
1239n/a '')
1240n/a self.assertEqual(domain_literal.domain, '[127.0.0.1]')
1241n/a self.assertEqual(domain_literal.ip, '127.0.0.1')
1242n/a
1243n/a def test_get_domain_literal_with_surrounding_cfws(self):
1244n/a domain_literal = self._test_get_x(parser.get_domain_literal,
1245n/a '(foo)[ 127.0.0.1] (bar)',
1246n/a '(foo)[ 127.0.0.1] (bar)',
1247n/a ' [ 127.0.0.1] ',
1248n/a [],
1249n/a '')
1250n/a self.assertEqual(domain_literal.domain, '[127.0.0.1]')
1251n/a self.assertEqual(domain_literal.ip, '127.0.0.1')
1252n/a
1253n/a def test_get_domain_literal_no_start_char_raises(self):
1254n/a with self.assertRaises(errors.HeaderParseError):
1255n/a parser.get_domain_literal('(foo) ')
1256n/a
1257n/a def test_get_domain_literal_no_start_char_before_special_raises(self):
1258n/a with self.assertRaises(errors.HeaderParseError):
1259n/a parser.get_domain_literal('(foo) @')
1260n/a
1261n/a def test_get_domain_literal_bad_dtext_char_before_special_raises(self):
1262n/a with self.assertRaises(errors.HeaderParseError):
1263n/a parser.get_domain_literal('(foo) [abc[@')
1264n/a
1265n/a # get_domain
1266n/a
1267n/a def test_get_domain_regular_domain_only(self):
1268n/a domain = self._test_get_x(parser.get_domain,
1269n/a 'example.com',
1270n/a 'example.com',
1271n/a 'example.com',
1272n/a [],
1273n/a '')
1274n/a self.assertEqual(domain.token_type, 'domain')
1275n/a self.assertEqual(domain.domain, 'example.com')
1276n/a
1277n/a def test_get_domain_domain_literal_only(self):
1278n/a domain = self._test_get_x(parser.get_domain,
1279n/a '[127.0.0.1]',
1280n/a '[127.0.0.1]',
1281n/a '[127.0.0.1]',
1282n/a [],
1283n/a '')
1284n/a self.assertEqual(domain.token_type, 'domain')
1285n/a self.assertEqual(domain.domain, '[127.0.0.1]')
1286n/a
1287n/a def test_get_domain_with_cfws(self):
1288n/a domain = self._test_get_x(parser.get_domain,
1289n/a '(foo) example.com(bar)\t',
1290n/a '(foo) example.com(bar)\t',
1291n/a ' example.com ',
1292n/a [],
1293n/a '')
1294n/a self.assertEqual(domain.domain, 'example.com')
1295n/a
1296n/a def test_get_domain_domain_literal_with_cfws(self):
1297n/a domain = self._test_get_x(parser.get_domain,
1298n/a '(foo)[127.0.0.1]\t(bar)',
1299n/a '(foo)[127.0.0.1]\t(bar)',
1300n/a ' [127.0.0.1] ',
1301n/a [],
1302n/a '')
1303n/a self.assertEqual(domain.domain, '[127.0.0.1]')
1304n/a
1305n/a def test_get_domain_domain_with_cfws_ends_at_special(self):
1306n/a domain = self._test_get_x(parser.get_domain,
1307n/a '(foo)example.com\t(bar), next',
1308n/a '(foo)example.com\t(bar)',
1309n/a ' example.com ',
1310n/a [],
1311n/a ', next')
1312n/a self.assertEqual(domain.domain, 'example.com')
1313n/a
1314n/a def test_get_domain_domain_literal_with_cfws_ends_at_special(self):
1315n/a domain = self._test_get_x(parser.get_domain,
1316n/a '(foo)[127.0.0.1]\t(bar), next',
1317n/a '(foo)[127.0.0.1]\t(bar)',
1318n/a ' [127.0.0.1] ',
1319n/a [],
1320n/a ', next')
1321n/a self.assertEqual(domain.domain, '[127.0.0.1]')
1322n/a
1323n/a def test_get_domain_obsolete(self):
1324n/a domain = self._test_get_x(parser.get_domain,
1325n/a '(foo) example . (bird)com(bar)\t',
1326n/a '(foo) example . (bird)com(bar)\t',
1327n/a ' example . com ',
1328n/a [errors.ObsoleteHeaderDefect],
1329n/a '')
1330n/a self.assertEqual(domain.domain, 'example.com')
1331n/a
1332n/a def test_get_domain_no_non_cfws_raises(self):
1333n/a with self.assertRaises(errors.HeaderParseError):
1334n/a parser.get_domain(" (foo)\t")
1335n/a
1336n/a def test_get_domain_no_atom_raises(self):
1337n/a with self.assertRaises(errors.HeaderParseError):
1338n/a parser.get_domain(" (foo)\t, broken")
1339n/a
1340n/a
1341n/a # get_addr_spec
1342n/a
1343n/a def test_get_addr_spec_normal(self):
1344n/a addr_spec = self._test_get_x(parser.get_addr_spec,
1345n/a 'dinsdale@example.com',
1346n/a 'dinsdale@example.com',
1347n/a 'dinsdale@example.com',
1348n/a [],
1349n/a '')
1350n/a self.assertEqual(addr_spec.token_type, 'addr-spec')
1351n/a self.assertEqual(addr_spec.local_part, 'dinsdale')
1352n/a self.assertEqual(addr_spec.domain, 'example.com')
1353n/a self.assertEqual(addr_spec.addr_spec, 'dinsdale@example.com')
1354n/a
1355n/a def test_get_addr_spec_with_doamin_literal(self):
1356n/a addr_spec = self._test_get_x(parser.get_addr_spec,
1357n/a 'dinsdale@[127.0.0.1]',
1358n/a 'dinsdale@[127.0.0.1]',
1359n/a 'dinsdale@[127.0.0.1]',
1360n/a [],
1361n/a '')
1362n/a self.assertEqual(addr_spec.local_part, 'dinsdale')
1363n/a self.assertEqual(addr_spec.domain, '[127.0.0.1]')
1364n/a self.assertEqual(addr_spec.addr_spec, 'dinsdale@[127.0.0.1]')
1365n/a
1366n/a def test_get_addr_spec_with_cfws(self):
1367n/a addr_spec = self._test_get_x(parser.get_addr_spec,
1368n/a '(foo) dinsdale(bar)@ (bird) example.com (bog)',
1369n/a '(foo) dinsdale(bar)@ (bird) example.com (bog)',
1370n/a ' dinsdale@example.com ',
1371n/a [],
1372n/a '')
1373n/a self.assertEqual(addr_spec.local_part, 'dinsdale')
1374n/a self.assertEqual(addr_spec.domain, 'example.com')
1375n/a self.assertEqual(addr_spec.addr_spec, 'dinsdale@example.com')
1376n/a
1377n/a def test_get_addr_spec_with_qouoted_string_and_cfws(self):
1378n/a addr_spec = self._test_get_x(parser.get_addr_spec,
1379n/a '(foo) "roy a bug"(bar)@ (bird) example.com (bog)',
1380n/a '(foo) "roy a bug"(bar)@ (bird) example.com (bog)',
1381n/a ' "roy a bug"@example.com ',
1382n/a [],
1383n/a '')
1384n/a self.assertEqual(addr_spec.local_part, 'roy a bug')
1385n/a self.assertEqual(addr_spec.domain, 'example.com')
1386n/a self.assertEqual(addr_spec.addr_spec, '"roy a bug"@example.com')
1387n/a
1388n/a def test_get_addr_spec_ends_at_special(self):
1389n/a addr_spec = self._test_get_x(parser.get_addr_spec,
1390n/a '(foo) "roy a bug"(bar)@ (bird) example.com (bog) , next',
1391n/a '(foo) "roy a bug"(bar)@ (bird) example.com (bog) ',
1392n/a ' "roy a bug"@example.com ',
1393n/a [],
1394n/a ', next')
1395n/a self.assertEqual(addr_spec.local_part, 'roy a bug')
1396n/a self.assertEqual(addr_spec.domain, 'example.com')
1397n/a self.assertEqual(addr_spec.addr_spec, '"roy a bug"@example.com')
1398n/a
1399n/a def test_get_addr_spec_quoted_strings_in_atom_list(self):
1400n/a addr_spec = self._test_get_x(parser.get_addr_spec,
1401n/a '""example" example"@example.com',
1402n/a '""example" example"@example.com',
1403n/a 'example example@example.com',
1404n/a [errors.InvalidHeaderDefect]*3,
1405n/a '')
1406n/a self.assertEqual(addr_spec.local_part, 'example example')
1407n/a self.assertEqual(addr_spec.domain, 'example.com')
1408n/a self.assertEqual(addr_spec.addr_spec, '"example example"@example.com')
1409n/a
1410n/a def test_get_addr_spec_dot_atom(self):
1411n/a addr_spec = self._test_get_x(parser.get_addr_spec,
1412n/a 'star.a.star@example.com',
1413n/a 'star.a.star@example.com',
1414n/a 'star.a.star@example.com',
1415n/a [],
1416n/a '')
1417n/a self.assertEqual(addr_spec.local_part, 'star.a.star')
1418n/a self.assertEqual(addr_spec.domain, 'example.com')
1419n/a self.assertEqual(addr_spec.addr_spec, 'star.a.star@example.com')
1420n/a
1421n/a # get_obs_route
1422n/a
1423n/a def test_get_obs_route_simple(self):
1424n/a obs_route = self._test_get_x(parser.get_obs_route,
1425n/a '@example.com, @two.example.com:',
1426n/a '@example.com, @two.example.com:',
1427n/a '@example.com, @two.example.com:',
1428n/a [],
1429n/a '')
1430n/a self.assertEqual(obs_route.token_type, 'obs-route')
1431n/a self.assertEqual(obs_route.domains, ['example.com', 'two.example.com'])
1432n/a
1433n/a def test_get_obs_route_complex(self):
1434n/a obs_route = self._test_get_x(parser.get_obs_route,
1435n/a '(foo),, (blue)@example.com (bar),@two.(foo) example.com (bird):',
1436n/a '(foo),, (blue)@example.com (bar),@two.(foo) example.com (bird):',
1437n/a ' ,, @example.com ,@two. example.com :',
1438n/a [errors.ObsoleteHeaderDefect], # This is the obs-domain
1439n/a '')
1440n/a self.assertEqual(obs_route.token_type, 'obs-route')
1441n/a self.assertEqual(obs_route.domains, ['example.com', 'two.example.com'])
1442n/a
1443n/a def test_get_obs_route_no_route_before_end_raises(self):
1444n/a with self.assertRaises(errors.HeaderParseError):
1445n/a parser.get_obs_route('(foo) @example.com,')
1446n/a
1447n/a def test_get_obs_route_no_route_before_special_raises(self):
1448n/a with self.assertRaises(errors.HeaderParseError):
1449n/a parser.get_obs_route('(foo) [abc],')
1450n/a
1451n/a def test_get_obs_route_no_route_before_special_raises2(self):
1452n/a with self.assertRaises(errors.HeaderParseError):
1453n/a parser.get_obs_route('(foo) @example.com [abc],')
1454n/a
1455n/a # get_angle_addr
1456n/a
1457n/a def test_get_angle_addr_simple(self):
1458n/a angle_addr = self._test_get_x(parser.get_angle_addr,
1459n/a '<dinsdale@example.com>',
1460n/a '<dinsdale@example.com>',
1461n/a '<dinsdale@example.com>',
1462n/a [],
1463n/a '')
1464n/a self.assertEqual(angle_addr.token_type, 'angle-addr')
1465n/a self.assertEqual(angle_addr.local_part, 'dinsdale')
1466n/a self.assertEqual(angle_addr.domain, 'example.com')
1467n/a self.assertIsNone(angle_addr.route)
1468n/a self.assertEqual(angle_addr.addr_spec, 'dinsdale@example.com')
1469n/a
1470n/a def test_get_angle_addr_empty(self):
1471n/a angle_addr = self._test_get_x(parser.get_angle_addr,
1472n/a '<>',
1473n/a '<>',
1474n/a '<>',
1475n/a [errors.InvalidHeaderDefect],
1476n/a '')
1477n/a self.assertEqual(angle_addr.token_type, 'angle-addr')
1478n/a self.assertIsNone(angle_addr.local_part)
1479n/a self.assertIsNone(angle_addr.domain)
1480n/a self.assertIsNone(angle_addr.route)
1481n/a self.assertEqual(angle_addr.addr_spec, '<>')
1482n/a
1483n/a def test_get_angle_addr_with_cfws(self):
1484n/a angle_addr = self._test_get_x(parser.get_angle_addr,
1485n/a ' (foo) <dinsdale@example.com>(bar)',
1486n/a ' (foo) <dinsdale@example.com>(bar)',
1487n/a ' <dinsdale@example.com> ',
1488n/a [],
1489n/a '')
1490n/a self.assertEqual(angle_addr.token_type, 'angle-addr')
1491n/a self.assertEqual(angle_addr.local_part, 'dinsdale')
1492n/a self.assertEqual(angle_addr.domain, 'example.com')
1493n/a self.assertIsNone(angle_addr.route)
1494n/a self.assertEqual(angle_addr.addr_spec, 'dinsdale@example.com')
1495n/a
1496n/a def test_get_angle_addr_qs_and_domain_literal(self):
1497n/a angle_addr = self._test_get_x(parser.get_angle_addr,
1498n/a '<"Fred Perfect"@[127.0.0.1]>',
1499n/a '<"Fred Perfect"@[127.0.0.1]>',
1500n/a '<"Fred Perfect"@[127.0.0.1]>',
1501n/a [],
1502n/a '')
1503n/a self.assertEqual(angle_addr.local_part, 'Fred Perfect')
1504n/a self.assertEqual(angle_addr.domain, '[127.0.0.1]')
1505n/a self.assertIsNone(angle_addr.route)
1506n/a self.assertEqual(angle_addr.addr_spec, '"Fred Perfect"@[127.0.0.1]')
1507n/a
1508n/a def test_get_angle_addr_internal_cfws(self):
1509n/a angle_addr = self._test_get_x(parser.get_angle_addr,
1510n/a '<(foo) dinsdale@example.com(bar)>',
1511n/a '<(foo) dinsdale@example.com(bar)>',
1512n/a '< dinsdale@example.com >',
1513n/a [],
1514n/a '')
1515n/a self.assertEqual(angle_addr.local_part, 'dinsdale')
1516n/a self.assertEqual(angle_addr.domain, 'example.com')
1517n/a self.assertIsNone(angle_addr.route)
1518n/a self.assertEqual(angle_addr.addr_spec, 'dinsdale@example.com')
1519n/a
1520n/a def test_get_angle_addr_obs_route(self):
1521n/a angle_addr = self._test_get_x(parser.get_angle_addr,
1522n/a '(foo)<@example.com, (bird) @two.example.com: dinsdale@example.com> (bar) ',
1523n/a '(foo)<@example.com, (bird) @two.example.com: dinsdale@example.com> (bar) ',
1524n/a ' <@example.com, @two.example.com: dinsdale@example.com> ',
1525n/a [errors.ObsoleteHeaderDefect],
1526n/a '')
1527n/a self.assertEqual(angle_addr.local_part, 'dinsdale')
1528n/a self.assertEqual(angle_addr.domain, 'example.com')
1529n/a self.assertEqual(angle_addr.route, ['example.com', 'two.example.com'])
1530n/a self.assertEqual(angle_addr.addr_spec, 'dinsdale@example.com')
1531n/a
1532n/a def test_get_angle_addr_missing_closing_angle(self):
1533n/a angle_addr = self._test_get_x(parser.get_angle_addr,
1534n/a '<dinsdale@example.com',
1535n/a '<dinsdale@example.com>',
1536n/a '<dinsdale@example.com>',
1537n/a [errors.InvalidHeaderDefect],
1538n/a '')
1539n/a self.assertEqual(angle_addr.local_part, 'dinsdale')
1540n/a self.assertEqual(angle_addr.domain, 'example.com')
1541n/a self.assertIsNone(angle_addr.route)
1542n/a self.assertEqual(angle_addr.addr_spec, 'dinsdale@example.com')
1543n/a
1544n/a def test_get_angle_addr_missing_closing_angle_with_cfws(self):
1545n/a angle_addr = self._test_get_x(parser.get_angle_addr,
1546n/a '<dinsdale@example.com (foo)',
1547n/a '<dinsdale@example.com (foo)>',
1548n/a '<dinsdale@example.com >',
1549n/a [errors.InvalidHeaderDefect],
1550n/a '')
1551n/a self.assertEqual(angle_addr.local_part, 'dinsdale')
1552n/a self.assertEqual(angle_addr.domain, 'example.com')
1553n/a self.assertIsNone(angle_addr.route)
1554n/a self.assertEqual(angle_addr.addr_spec, 'dinsdale@example.com')
1555n/a
1556n/a def test_get_angle_addr_ends_at_special(self):
1557n/a angle_addr = self._test_get_x(parser.get_angle_addr,
1558n/a '<dinsdale@example.com> (foo), next',
1559n/a '<dinsdale@example.com> (foo)',
1560n/a '<dinsdale@example.com> ',
1561n/a [],
1562n/a ', next')
1563n/a self.assertEqual(angle_addr.local_part, 'dinsdale')
1564n/a self.assertEqual(angle_addr.domain, 'example.com')
1565n/a self.assertIsNone(angle_addr.route)
1566n/a self.assertEqual(angle_addr.addr_spec, 'dinsdale@example.com')
1567n/a
1568n/a def test_get_angle_addr_no_angle_raise(self):
1569n/a with self.assertRaises(errors.HeaderParseError):
1570n/a parser.get_angle_addr('(foo) ')
1571n/a
1572n/a def test_get_angle_addr_no_angle_before_special_raises(self):
1573n/a with self.assertRaises(errors.HeaderParseError):
1574n/a parser.get_angle_addr('(foo) , next')
1575n/a
1576n/a def test_get_angle_addr_no_angle_raises(self):
1577n/a with self.assertRaises(errors.HeaderParseError):
1578n/a parser.get_angle_addr('bar')
1579n/a
1580n/a def test_get_angle_addr_special_after_angle_raises(self):
1581n/a with self.assertRaises(errors.HeaderParseError):
1582n/a parser.get_angle_addr('(foo) <, bar')
1583n/a
1584n/a # get_display_name This is phrase but with a different value.
1585n/a
1586n/a def test_get_display_name_simple(self):
1587n/a display_name = self._test_get_x(parser.get_display_name,
1588n/a 'Fred A Johnson',
1589n/a 'Fred A Johnson',
1590n/a 'Fred A Johnson',
1591n/a [],
1592n/a '')
1593n/a self.assertEqual(display_name.token_type, 'display-name')
1594n/a self.assertEqual(display_name.display_name, 'Fred A Johnson')
1595n/a
1596n/a def test_get_display_name_complex1(self):
1597n/a display_name = self._test_get_x(parser.get_display_name,
1598n/a '"Fred A. Johnson" is his name, oh.',
1599n/a '"Fred A. Johnson" is his name',
1600n/a '"Fred A. Johnson is his name"',
1601n/a [],
1602n/a ', oh.')
1603n/a self.assertEqual(display_name.token_type, 'display-name')
1604n/a self.assertEqual(display_name.display_name, 'Fred A. Johnson is his name')
1605n/a
1606n/a def test_get_display_name_complex2(self):
1607n/a display_name = self._test_get_x(parser.get_display_name,
1608n/a ' (A) bird (in (my|your)) "hand " is messy\t<>\t',
1609n/a ' (A) bird (in (my|your)) "hand " is messy\t',
1610n/a ' "bird hand is messy" ',
1611n/a [],
1612n/a '<>\t')
1613n/a self.assertEqual(display_name[0][0].comments, ['A'])
1614n/a self.assertEqual(display_name[0][2].comments, ['in (my|your)'])
1615n/a self.assertEqual(display_name.display_name, 'bird hand is messy')
1616n/a
1617n/a def test_get_display_name_obsolete(self):
1618n/a display_name = self._test_get_x(parser.get_display_name,
1619n/a 'Fred A.(weird).O Johnson',
1620n/a 'Fred A.(weird).O Johnson',
1621n/a '"Fred A. .O Johnson"',
1622n/a [errors.ObsoleteHeaderDefect]*3,
1623n/a '')
1624n/a self.assertEqual(len(display_name), 7)
1625n/a self.assertEqual(display_name[3].comments, ['weird'])
1626n/a self.assertEqual(display_name.display_name, 'Fred A. .O Johnson')
1627n/a
1628n/a def test_get_display_name_pharse_must_start_with_word(self):
1629n/a display_name = self._test_get_x(parser.get_display_name,
1630n/a '(even weirder).name',
1631n/a '(even weirder).name',
1632n/a ' ".name"',
1633n/a [errors.InvalidHeaderDefect] + [errors.ObsoleteHeaderDefect]*2,
1634n/a '')
1635n/a self.assertEqual(len(display_name), 3)
1636n/a self.assertEqual(display_name[0].comments, ['even weirder'])
1637n/a self.assertEqual(display_name.display_name, '.name')
1638n/a
1639n/a def test_get_display_name_ending_with_obsolete(self):
1640n/a display_name = self._test_get_x(parser.get_display_name,
1641n/a 'simple phrase.(with trailing comment):boo',
1642n/a 'simple phrase.(with trailing comment)',
1643n/a '"simple phrase." ',
1644n/a [errors.ObsoleteHeaderDefect]*2,
1645n/a ':boo')
1646n/a self.assertEqual(len(display_name), 4)
1647n/a self.assertEqual(display_name[3].comments, ['with trailing comment'])
1648n/a self.assertEqual(display_name.display_name, 'simple phrase.')
1649n/a
1650n/a # get_name_addr
1651n/a
1652n/a def test_get_name_addr_angle_addr_only(self):
1653n/a name_addr = self._test_get_x(parser.get_name_addr,
1654n/a '<dinsdale@example.com>',
1655n/a '<dinsdale@example.com>',
1656n/a '<dinsdale@example.com>',
1657n/a [],
1658n/a '')
1659n/a self.assertEqual(name_addr.token_type, 'name-addr')
1660n/a self.assertIsNone(name_addr.display_name)
1661n/a self.assertEqual(name_addr.local_part, 'dinsdale')
1662n/a self.assertEqual(name_addr.domain, 'example.com')
1663n/a self.assertIsNone(name_addr.route)
1664n/a self.assertEqual(name_addr.addr_spec, 'dinsdale@example.com')
1665n/a
1666n/a def test_get_name_addr_atom_name(self):
1667n/a name_addr = self._test_get_x(parser.get_name_addr,
1668n/a 'Dinsdale <dinsdale@example.com>',
1669n/a 'Dinsdale <dinsdale@example.com>',
1670n/a 'Dinsdale <dinsdale@example.com>',
1671n/a [],
1672n/a '')
1673n/a self.assertEqual(name_addr.token_type, 'name-addr')
1674n/a self.assertEqual(name_addr.display_name, 'Dinsdale')
1675n/a self.assertEqual(name_addr.local_part, 'dinsdale')
1676n/a self.assertEqual(name_addr.domain, 'example.com')
1677n/a self.assertIsNone(name_addr.route)
1678n/a self.assertEqual(name_addr.addr_spec, 'dinsdale@example.com')
1679n/a
1680n/a def test_get_name_addr_atom_name_with_cfws(self):
1681n/a name_addr = self._test_get_x(parser.get_name_addr,
1682n/a '(foo) Dinsdale (bar) <dinsdale@example.com> (bird)',
1683n/a '(foo) Dinsdale (bar) <dinsdale@example.com> (bird)',
1684n/a ' Dinsdale <dinsdale@example.com> ',
1685n/a [],
1686n/a '')
1687n/a self.assertEqual(name_addr.display_name, 'Dinsdale')
1688n/a self.assertEqual(name_addr.local_part, 'dinsdale')
1689n/a self.assertEqual(name_addr.domain, 'example.com')
1690n/a self.assertIsNone(name_addr.route)
1691n/a self.assertEqual(name_addr.addr_spec, 'dinsdale@example.com')
1692n/a
1693n/a def test_get_name_addr_name_with_cfws_and_dots(self):
1694n/a name_addr = self._test_get_x(parser.get_name_addr,
1695n/a '(foo) Roy.A.Bear (bar) <dinsdale@example.com> (bird)',
1696n/a '(foo) Roy.A.Bear (bar) <dinsdale@example.com> (bird)',
1697n/a ' "Roy.A.Bear" <dinsdale@example.com> ',
1698n/a [errors.ObsoleteHeaderDefect]*2,
1699n/a '')
1700n/a self.assertEqual(name_addr.display_name, 'Roy.A.Bear')
1701n/a self.assertEqual(name_addr.local_part, 'dinsdale')
1702n/a self.assertEqual(name_addr.domain, 'example.com')
1703n/a self.assertIsNone(name_addr.route)
1704n/a self.assertEqual(name_addr.addr_spec, 'dinsdale@example.com')
1705n/a
1706n/a def test_get_name_addr_qs_name(self):
1707n/a name_addr = self._test_get_x(parser.get_name_addr,
1708n/a '"Roy.A.Bear" <dinsdale@example.com>',
1709n/a '"Roy.A.Bear" <dinsdale@example.com>',
1710n/a '"Roy.A.Bear" <dinsdale@example.com>',
1711n/a [],
1712n/a '')
1713n/a self.assertEqual(name_addr.display_name, 'Roy.A.Bear')
1714n/a self.assertEqual(name_addr.local_part, 'dinsdale')
1715n/a self.assertEqual(name_addr.domain, 'example.com')
1716n/a self.assertIsNone(name_addr.route)
1717n/a self.assertEqual(name_addr.addr_spec, 'dinsdale@example.com')
1718n/a
1719n/a def test_get_name_addr_with_route(self):
1720n/a name_addr = self._test_get_x(parser.get_name_addr,
1721n/a '"Roy.A.Bear" <@two.example.com: dinsdale@example.com>',
1722n/a '"Roy.A.Bear" <@two.example.com: dinsdale@example.com>',
1723n/a '"Roy.A.Bear" <@two.example.com: dinsdale@example.com>',
1724n/a [errors.ObsoleteHeaderDefect],
1725n/a '')
1726n/a self.assertEqual(name_addr.display_name, 'Roy.A.Bear')
1727n/a self.assertEqual(name_addr.local_part, 'dinsdale')
1728n/a self.assertEqual(name_addr.domain, 'example.com')
1729n/a self.assertEqual(name_addr.route, ['two.example.com'])
1730n/a self.assertEqual(name_addr.addr_spec, 'dinsdale@example.com')
1731n/a
1732n/a def test_get_name_addr_ends_at_special(self):
1733n/a name_addr = self._test_get_x(parser.get_name_addr,
1734n/a '"Roy.A.Bear" <dinsdale@example.com>, next',
1735n/a '"Roy.A.Bear" <dinsdale@example.com>',
1736n/a '"Roy.A.Bear" <dinsdale@example.com>',
1737n/a [],
1738n/a ', next')
1739n/a self.assertEqual(name_addr.display_name, 'Roy.A.Bear')
1740n/a self.assertEqual(name_addr.local_part, 'dinsdale')
1741n/a self.assertEqual(name_addr.domain, 'example.com')
1742n/a self.assertIsNone(name_addr.route)
1743n/a self.assertEqual(name_addr.addr_spec, 'dinsdale@example.com')
1744n/a
1745n/a def test_get_name_addr_no_content_raises(self):
1746n/a with self.assertRaises(errors.HeaderParseError):
1747n/a parser.get_name_addr(' (foo) ')
1748n/a
1749n/a def test_get_name_addr_no_content_before_special_raises(self):
1750n/a with self.assertRaises(errors.HeaderParseError):
1751n/a parser.get_name_addr(' (foo) ,')
1752n/a
1753n/a def test_get_name_addr_no_angle_after_display_name_raises(self):
1754n/a with self.assertRaises(errors.HeaderParseError):
1755n/a parser.get_name_addr('foo bar')
1756n/a
1757n/a # get_mailbox
1758n/a
1759n/a def test_get_mailbox_addr_spec_only(self):
1760n/a mailbox = self._test_get_x(parser.get_mailbox,
1761n/a 'dinsdale@example.com',
1762n/a 'dinsdale@example.com',
1763n/a 'dinsdale@example.com',
1764n/a [],
1765n/a '')
1766n/a self.assertEqual(mailbox.token_type, 'mailbox')
1767n/a self.assertIsNone(mailbox.display_name)
1768n/a self.assertEqual(mailbox.local_part, 'dinsdale')
1769n/a self.assertEqual(mailbox.domain, 'example.com')
1770n/a self.assertIsNone(mailbox.route)
1771n/a self.assertEqual(mailbox.addr_spec, 'dinsdale@example.com')
1772n/a
1773n/a def test_get_mailbox_angle_addr_only(self):
1774n/a mailbox = self._test_get_x(parser.get_mailbox,
1775n/a '<dinsdale@example.com>',
1776n/a '<dinsdale@example.com>',
1777n/a '<dinsdale@example.com>',
1778n/a [],
1779n/a '')
1780n/a self.assertEqual(mailbox.token_type, 'mailbox')
1781n/a self.assertIsNone(mailbox.display_name)
1782n/a self.assertEqual(mailbox.local_part, 'dinsdale')
1783n/a self.assertEqual(mailbox.domain, 'example.com')
1784n/a self.assertIsNone(mailbox.route)
1785n/a self.assertEqual(mailbox.addr_spec, 'dinsdale@example.com')
1786n/a
1787n/a def test_get_mailbox_name_addr(self):
1788n/a mailbox = self._test_get_x(parser.get_mailbox,
1789n/a '"Roy A. Bear" <dinsdale@example.com>',
1790n/a '"Roy A. Bear" <dinsdale@example.com>',
1791n/a '"Roy A. Bear" <dinsdale@example.com>',
1792n/a [],
1793n/a '')
1794n/a self.assertEqual(mailbox.token_type, 'mailbox')
1795n/a self.assertEqual(mailbox.display_name, 'Roy A. Bear')
1796n/a self.assertEqual(mailbox.local_part, 'dinsdale')
1797n/a self.assertEqual(mailbox.domain, 'example.com')
1798n/a self.assertIsNone(mailbox.route)
1799n/a self.assertEqual(mailbox.addr_spec, 'dinsdale@example.com')
1800n/a
1801n/a def test_get_mailbox_ends_at_special(self):
1802n/a mailbox = self._test_get_x(parser.get_mailbox,
1803n/a '"Roy A. Bear" <dinsdale@example.com>, rest',
1804n/a '"Roy A. Bear" <dinsdale@example.com>',
1805n/a '"Roy A. Bear" <dinsdale@example.com>',
1806n/a [],
1807n/a ', rest')
1808n/a self.assertEqual(mailbox.token_type, 'mailbox')
1809n/a self.assertEqual(mailbox.display_name, 'Roy A. Bear')
1810n/a self.assertEqual(mailbox.local_part, 'dinsdale')
1811n/a self.assertEqual(mailbox.domain, 'example.com')
1812n/a self.assertIsNone(mailbox.route)
1813n/a self.assertEqual(mailbox.addr_spec, 'dinsdale@example.com')
1814n/a
1815n/a def test_get_mailbox_quoted_strings_in_atom_list(self):
1816n/a mailbox = self._test_get_x(parser.get_mailbox,
1817n/a '""example" example"@example.com',
1818n/a '""example" example"@example.com',
1819n/a 'example example@example.com',
1820n/a [errors.InvalidHeaderDefect]*3,
1821n/a '')
1822n/a self.assertEqual(mailbox.local_part, 'example example')
1823n/a self.assertEqual(mailbox.domain, 'example.com')
1824n/a self.assertEqual(mailbox.addr_spec, '"example example"@example.com')
1825n/a
1826n/a # get_mailbox_list
1827n/a
1828n/a def test_get_mailbox_list_single_addr(self):
1829n/a mailbox_list = self._test_get_x(parser.get_mailbox_list,
1830n/a 'dinsdale@example.com',
1831n/a 'dinsdale@example.com',
1832n/a 'dinsdale@example.com',
1833n/a [],
1834n/a '')
1835n/a self.assertEqual(mailbox_list.token_type, 'mailbox-list')
1836n/a self.assertEqual(len(mailbox_list.mailboxes), 1)
1837n/a mailbox = mailbox_list.mailboxes[0]
1838n/a self.assertIsNone(mailbox.display_name)
1839n/a self.assertEqual(mailbox.local_part, 'dinsdale')
1840n/a self.assertEqual(mailbox.domain, 'example.com')
1841n/a self.assertIsNone(mailbox.route)
1842n/a self.assertEqual(mailbox.addr_spec, 'dinsdale@example.com')
1843n/a self.assertEqual(mailbox_list.mailboxes,
1844n/a mailbox_list.all_mailboxes)
1845n/a
1846n/a def test_get_mailbox_list_two_simple_addr(self):
1847n/a mailbox_list = self._test_get_x(parser.get_mailbox_list,
1848n/a 'dinsdale@example.com, dinsdale@test.example.com',
1849n/a 'dinsdale@example.com, dinsdale@test.example.com',
1850n/a 'dinsdale@example.com, dinsdale@test.example.com',
1851n/a [],
1852n/a '')
1853n/a self.assertEqual(mailbox_list.token_type, 'mailbox-list')
1854n/a self.assertEqual(len(mailbox_list.mailboxes), 2)
1855n/a self.assertEqual(mailbox_list.mailboxes[0].addr_spec,
1856n/a 'dinsdale@example.com')
1857n/a self.assertEqual(mailbox_list.mailboxes[1].addr_spec,
1858n/a 'dinsdale@test.example.com')
1859n/a self.assertEqual(mailbox_list.mailboxes,
1860n/a mailbox_list.all_mailboxes)
1861n/a
1862n/a def test_get_mailbox_list_two_name_addr(self):
1863n/a mailbox_list = self._test_get_x(parser.get_mailbox_list,
1864n/a ('"Roy A. Bear" <dinsdale@example.com>,'
1865n/a ' "Fred Flintstone" <dinsdale@test.example.com>'),
1866n/a ('"Roy A. Bear" <dinsdale@example.com>,'
1867n/a ' "Fred Flintstone" <dinsdale@test.example.com>'),
1868n/a ('"Roy A. Bear" <dinsdale@example.com>,'
1869n/a ' "Fred Flintstone" <dinsdale@test.example.com>'),
1870n/a [],
1871n/a '')
1872n/a self.assertEqual(len(mailbox_list.mailboxes), 2)
1873n/a self.assertEqual(mailbox_list.mailboxes[0].addr_spec,
1874n/a 'dinsdale@example.com')
1875n/a self.assertEqual(mailbox_list.mailboxes[0].display_name,
1876n/a 'Roy A. Bear')
1877n/a self.assertEqual(mailbox_list.mailboxes[1].addr_spec,
1878n/a 'dinsdale@test.example.com')
1879n/a self.assertEqual(mailbox_list.mailboxes[1].display_name,
1880n/a 'Fred Flintstone')
1881n/a self.assertEqual(mailbox_list.mailboxes,
1882n/a mailbox_list.all_mailboxes)
1883n/a
1884n/a def test_get_mailbox_list_two_complex(self):
1885n/a mailbox_list = self._test_get_x(parser.get_mailbox_list,
1886n/a ('(foo) "Roy A. Bear" <dinsdale@example.com>(bar),'
1887n/a ' "Fred Flintstone" <dinsdale@test.(bird)example.com>'),
1888n/a ('(foo) "Roy A. Bear" <dinsdale@example.com>(bar),'
1889n/a ' "Fred Flintstone" <dinsdale@test.(bird)example.com>'),
1890n/a (' "Roy A. Bear" <dinsdale@example.com> ,'
1891n/a ' "Fred Flintstone" <dinsdale@test. example.com>'),
1892n/a [errors.ObsoleteHeaderDefect],
1893n/a '')
1894n/a self.assertEqual(len(mailbox_list.mailboxes), 2)
1895n/a self.assertEqual(mailbox_list.mailboxes[0].addr_spec,
1896n/a 'dinsdale@example.com')
1897n/a self.assertEqual(mailbox_list.mailboxes[0].display_name,
1898n/a 'Roy A. Bear')
1899n/a self.assertEqual(mailbox_list.mailboxes[1].addr_spec,
1900n/a 'dinsdale@test.example.com')
1901n/a self.assertEqual(mailbox_list.mailboxes[1].display_name,
1902n/a 'Fred Flintstone')
1903n/a self.assertEqual(mailbox_list.mailboxes,
1904n/a mailbox_list.all_mailboxes)
1905n/a
1906n/a def test_get_mailbox_list_unparseable_mailbox_null(self):
1907n/a mailbox_list = self._test_get_x(parser.get_mailbox_list,
1908n/a ('"Roy A. Bear"[] dinsdale@example.com,'
1909n/a ' "Fred Flintstone" <dinsdale@test.(bird)example.com>'),
1910n/a ('"Roy A. Bear"[] dinsdale@example.com,'
1911n/a ' "Fred Flintstone" <dinsdale@test.(bird)example.com>'),
1912n/a ('"Roy A. Bear"[] dinsdale@example.com,'
1913n/a ' "Fred Flintstone" <dinsdale@test. example.com>'),
1914n/a [errors.InvalidHeaderDefect, # the 'extra' text after the local part
1915n/a errors.InvalidHeaderDefect, # the local part with no angle-addr
1916n/a errors.ObsoleteHeaderDefect, # period in extra text (example.com)
1917n/a errors.ObsoleteHeaderDefect], # (bird) in valid address.
1918n/a '')
1919n/a self.assertEqual(len(mailbox_list.mailboxes), 1)
1920n/a self.assertEqual(len(mailbox_list.all_mailboxes), 2)
1921n/a self.assertEqual(mailbox_list.all_mailboxes[0].token_type,
1922n/a 'invalid-mailbox')
1923n/a self.assertIsNone(mailbox_list.all_mailboxes[0].display_name)
1924n/a self.assertEqual(mailbox_list.all_mailboxes[0].local_part,
1925n/a 'Roy A. Bear')
1926n/a self.assertIsNone(mailbox_list.all_mailboxes[0].domain)
1927n/a self.assertEqual(mailbox_list.all_mailboxes[0].addr_spec,
1928n/a '"Roy A. Bear"')
1929n/a self.assertIs(mailbox_list.all_mailboxes[1],
1930n/a mailbox_list.mailboxes[0])
1931n/a self.assertEqual(mailbox_list.mailboxes[0].addr_spec,
1932n/a 'dinsdale@test.example.com')
1933n/a self.assertEqual(mailbox_list.mailboxes[0].display_name,
1934n/a 'Fred Flintstone')
1935n/a
1936n/a def test_get_mailbox_list_junk_after_valid_address(self):
1937n/a mailbox_list = self._test_get_x(parser.get_mailbox_list,
1938n/a ('"Roy A. Bear" <dinsdale@example.com>@@,'
1939n/a ' "Fred Flintstone" <dinsdale@test.example.com>'),
1940n/a ('"Roy A. Bear" <dinsdale@example.com>@@,'
1941n/a ' "Fred Flintstone" <dinsdale@test.example.com>'),
1942n/a ('"Roy A. Bear" <dinsdale@example.com>@@,'
1943n/a ' "Fred Flintstone" <dinsdale@test.example.com>'),
1944n/a [errors.InvalidHeaderDefect],
1945n/a '')
1946n/a self.assertEqual(len(mailbox_list.mailboxes), 1)
1947n/a self.assertEqual(len(mailbox_list.all_mailboxes), 2)
1948n/a self.assertEqual(mailbox_list.all_mailboxes[0].addr_spec,
1949n/a 'dinsdale@example.com')
1950n/a self.assertEqual(mailbox_list.all_mailboxes[0].display_name,
1951n/a 'Roy A. Bear')
1952n/a self.assertEqual(mailbox_list.all_mailboxes[0].token_type,
1953n/a 'invalid-mailbox')
1954n/a self.assertIs(mailbox_list.all_mailboxes[1],
1955n/a mailbox_list.mailboxes[0])
1956n/a self.assertEqual(mailbox_list.mailboxes[0].addr_spec,
1957n/a 'dinsdale@test.example.com')
1958n/a self.assertEqual(mailbox_list.mailboxes[0].display_name,
1959n/a 'Fred Flintstone')
1960n/a
1961n/a def test_get_mailbox_list_empty_list_element(self):
1962n/a mailbox_list = self._test_get_x(parser.get_mailbox_list,
1963n/a ('"Roy A. Bear" <dinsdale@example.com>, (bird),,'
1964n/a ' "Fred Flintstone" <dinsdale@test.example.com>'),
1965n/a ('"Roy A. Bear" <dinsdale@example.com>, (bird),,'
1966n/a ' "Fred Flintstone" <dinsdale@test.example.com>'),
1967n/a ('"Roy A. Bear" <dinsdale@example.com>, ,,'
1968n/a ' "Fred Flintstone" <dinsdale@test.example.com>'),
1969n/a [errors.ObsoleteHeaderDefect]*2,
1970n/a '')
1971n/a self.assertEqual(len(mailbox_list.mailboxes), 2)
1972n/a self.assertEqual(mailbox_list.all_mailboxes,
1973n/a mailbox_list.mailboxes)
1974n/a self.assertEqual(mailbox_list.all_mailboxes[0].addr_spec,
1975n/a 'dinsdale@example.com')
1976n/a self.assertEqual(mailbox_list.all_mailboxes[0].display_name,
1977n/a 'Roy A. Bear')
1978n/a self.assertEqual(mailbox_list.mailboxes[1].addr_spec,
1979n/a 'dinsdale@test.example.com')
1980n/a self.assertEqual(mailbox_list.mailboxes[1].display_name,
1981n/a 'Fred Flintstone')
1982n/a
1983n/a def test_get_mailbox_list_only_empty_elements(self):
1984n/a mailbox_list = self._test_get_x(parser.get_mailbox_list,
1985n/a '(foo),, (bar)',
1986n/a '(foo),, (bar)',
1987n/a ' ,, ',
1988n/a [errors.ObsoleteHeaderDefect]*3,
1989n/a '')
1990n/a self.assertEqual(len(mailbox_list.mailboxes), 0)
1991n/a self.assertEqual(mailbox_list.all_mailboxes,
1992n/a mailbox_list.mailboxes)
1993n/a
1994n/a # get_group_list
1995n/a
1996n/a def test_get_group_list_cfws_only(self):
1997n/a group_list = self._test_get_x(parser.get_group_list,
1998n/a '(hidden);',
1999n/a '(hidden)',
2000n/a ' ',
2001n/a [],
2002n/a ';')
2003n/a self.assertEqual(group_list.token_type, 'group-list')
2004n/a self.assertEqual(len(group_list.mailboxes), 0)
2005n/a self.assertEqual(group_list.mailboxes,
2006n/a group_list.all_mailboxes)
2007n/a
2008n/a def test_get_group_list_mailbox_list(self):
2009n/a group_list = self._test_get_x(parser.get_group_list,
2010n/a 'dinsdale@example.org, "Fred A. Bear" <dinsdale@example.org>',
2011n/a 'dinsdale@example.org, "Fred A. Bear" <dinsdale@example.org>',
2012n/a 'dinsdale@example.org, "Fred A. Bear" <dinsdale@example.org>',
2013n/a [],
2014n/a '')
2015n/a self.assertEqual(group_list.token_type, 'group-list')
2016n/a self.assertEqual(len(group_list.mailboxes), 2)
2017n/a self.assertEqual(group_list.mailboxes,
2018n/a group_list.all_mailboxes)
2019n/a self.assertEqual(group_list.mailboxes[1].display_name,
2020n/a 'Fred A. Bear')
2021n/a
2022n/a def test_get_group_list_obs_group_list(self):
2023n/a group_list = self._test_get_x(parser.get_group_list,
2024n/a ', (foo),,(bar)',
2025n/a ', (foo),,(bar)',
2026n/a ', ,, ',
2027n/a [errors.ObsoleteHeaderDefect],
2028n/a '')
2029n/a self.assertEqual(group_list.token_type, 'group-list')
2030n/a self.assertEqual(len(group_list.mailboxes), 0)
2031n/a self.assertEqual(group_list.mailboxes,
2032n/a group_list.all_mailboxes)
2033n/a
2034n/a def test_get_group_list_comment_only_invalid(self):
2035n/a group_list = self._test_get_x(parser.get_group_list,
2036n/a '(bar)',
2037n/a '(bar)',
2038n/a ' ',
2039n/a [errors.InvalidHeaderDefect],
2040n/a '')
2041n/a self.assertEqual(group_list.token_type, 'group-list')
2042n/a self.assertEqual(len(group_list.mailboxes), 0)
2043n/a self.assertEqual(group_list.mailboxes,
2044n/a group_list.all_mailboxes)
2045n/a
2046n/a # get_group
2047n/a
2048n/a def test_get_group_empty(self):
2049n/a group = self._test_get_x(parser.get_group,
2050n/a 'Monty Python:;',
2051n/a 'Monty Python:;',
2052n/a 'Monty Python:;',
2053n/a [],
2054n/a '')
2055n/a self.assertEqual(group.token_type, 'group')
2056n/a self.assertEqual(group.display_name, 'Monty Python')
2057n/a self.assertEqual(len(group.mailboxes), 0)
2058n/a self.assertEqual(group.mailboxes,
2059n/a group.all_mailboxes)
2060n/a
2061n/a def test_get_group_null_addr_spec(self):
2062n/a group = self._test_get_x(parser.get_group,
2063n/a 'foo: <>;',
2064n/a 'foo: <>;',
2065n/a 'foo: <>;',
2066n/a [errors.InvalidHeaderDefect],
2067n/a '')
2068n/a self.assertEqual(group.display_name, 'foo')
2069n/a self.assertEqual(len(group.mailboxes), 0)
2070n/a self.assertEqual(len(group.all_mailboxes), 1)
2071n/a self.assertEqual(group.all_mailboxes[0].value, '<>')
2072n/a
2073n/a def test_get_group_cfws_only(self):
2074n/a group = self._test_get_x(parser.get_group,
2075n/a 'Monty Python: (hidden);',
2076n/a 'Monty Python: (hidden);',
2077n/a 'Monty Python: ;',
2078n/a [],
2079n/a '')
2080n/a self.assertEqual(group.token_type, 'group')
2081n/a self.assertEqual(group.display_name, 'Monty Python')
2082n/a self.assertEqual(len(group.mailboxes), 0)
2083n/a self.assertEqual(group.mailboxes,
2084n/a group.all_mailboxes)
2085n/a
2086n/a def test_get_group_single_mailbox(self):
2087n/a group = self._test_get_x(parser.get_group,
2088n/a 'Monty Python: "Fred A. Bear" <dinsdale@example.com>;',
2089n/a 'Monty Python: "Fred A. Bear" <dinsdale@example.com>;',
2090n/a 'Monty Python: "Fred A. Bear" <dinsdale@example.com>;',
2091n/a [],
2092n/a '')
2093n/a self.assertEqual(group.token_type, 'group')
2094n/a self.assertEqual(group.display_name, 'Monty Python')
2095n/a self.assertEqual(len(group.mailboxes), 1)
2096n/a self.assertEqual(group.mailboxes,
2097n/a group.all_mailboxes)
2098n/a self.assertEqual(group.mailboxes[0].addr_spec,
2099n/a 'dinsdale@example.com')
2100n/a
2101n/a def test_get_group_mixed_list(self):
2102n/a group = self._test_get_x(parser.get_group,
2103n/a ('Monty Python: "Fred A. Bear" <dinsdale@example.com>,'
2104n/a '(foo) Roger <ping@exampele.com>, x@test.example.com;'),
2105n/a ('Monty Python: "Fred A. Bear" <dinsdale@example.com>,'
2106n/a '(foo) Roger <ping@exampele.com>, x@test.example.com;'),
2107n/a ('Monty Python: "Fred A. Bear" <dinsdale@example.com>,'
2108n/a ' Roger <ping@exampele.com>, x@test.example.com;'),
2109n/a [],
2110n/a '')
2111n/a self.assertEqual(group.token_type, 'group')
2112n/a self.assertEqual(group.display_name, 'Monty Python')
2113n/a self.assertEqual(len(group.mailboxes), 3)
2114n/a self.assertEqual(group.mailboxes,
2115n/a group.all_mailboxes)
2116n/a self.assertEqual(group.mailboxes[0].display_name,
2117n/a 'Fred A. Bear')
2118n/a self.assertEqual(group.mailboxes[1].display_name,
2119n/a 'Roger')
2120n/a self.assertEqual(group.mailboxes[2].local_part, 'x')
2121n/a
2122n/a def test_get_group_one_invalid(self):
2123n/a group = self._test_get_x(parser.get_group,
2124n/a ('Monty Python: "Fred A. Bear" <dinsdale@example.com>,'
2125n/a '(foo) Roger ping@exampele.com, x@test.example.com;'),
2126n/a ('Monty Python: "Fred A. Bear" <dinsdale@example.com>,'
2127n/a '(foo) Roger ping@exampele.com, x@test.example.com;'),
2128n/a ('Monty Python: "Fred A. Bear" <dinsdale@example.com>,'
2129n/a ' Roger ping@exampele.com, x@test.example.com;'),
2130n/a [errors.InvalidHeaderDefect, # non-angle addr makes local part invalid
2131n/a errors.InvalidHeaderDefect], # and its not obs-local either: no dots.
2132n/a '')
2133n/a self.assertEqual(group.token_type, 'group')
2134n/a self.assertEqual(group.display_name, 'Monty Python')
2135n/a self.assertEqual(len(group.mailboxes), 2)
2136n/a self.assertEqual(len(group.all_mailboxes), 3)
2137n/a self.assertEqual(group.mailboxes[0].display_name,
2138n/a 'Fred A. Bear')
2139n/a self.assertEqual(group.mailboxes[1].local_part, 'x')
2140n/a self.assertIsNone(group.all_mailboxes[1].display_name)
2141n/a
2142n/a # get_address
2143n/a
2144n/a def test_get_address_simple(self):
2145n/a address = self._test_get_x(parser.get_address,
2146n/a 'dinsdale@example.com',
2147n/a 'dinsdale@example.com',
2148n/a 'dinsdale@example.com',
2149n/a [],
2150n/a '')
2151n/a self.assertEqual(address.token_type, 'address')
2152n/a self.assertEqual(len(address.mailboxes), 1)
2153n/a self.assertEqual(address.mailboxes,
2154n/a address.all_mailboxes)
2155n/a self.assertEqual(address.mailboxes[0].domain,
2156n/a 'example.com')
2157n/a self.assertEqual(address[0].token_type,
2158n/a 'mailbox')
2159n/a
2160n/a def test_get_address_complex(self):
2161n/a address = self._test_get_x(parser.get_address,
2162n/a '(foo) "Fred A. Bear" <(bird)dinsdale@example.com>',
2163n/a '(foo) "Fred A. Bear" <(bird)dinsdale@example.com>',
2164n/a ' "Fred A. Bear" < dinsdale@example.com>',
2165n/a [],
2166n/a '')
2167n/a self.assertEqual(address.token_type, 'address')
2168n/a self.assertEqual(len(address.mailboxes), 1)
2169n/a self.assertEqual(address.mailboxes,
2170n/a address.all_mailboxes)
2171n/a self.assertEqual(address.mailboxes[0].display_name,
2172n/a 'Fred A. Bear')
2173n/a self.assertEqual(address[0].token_type,
2174n/a 'mailbox')
2175n/a
2176n/a def test_get_address_rfc2047_display_name(self):
2177n/a address = self._test_get_x(parser.get_address,
2178n/a '=?utf-8?q?=C3=89ric?= <foo@example.com>',
2179n/a 'Éric <foo@example.com>',
2180n/a 'Éric <foo@example.com>',
2181n/a [],
2182n/a '')
2183n/a self.assertEqual(address.token_type, 'address')
2184n/a self.assertEqual(len(address.mailboxes), 1)
2185n/a self.assertEqual(address.mailboxes,
2186n/a address.all_mailboxes)
2187n/a self.assertEqual(address.mailboxes[0].display_name,
2188n/a 'Éric')
2189n/a self.assertEqual(address[0].token_type,
2190n/a 'mailbox')
2191n/a
2192n/a def test_get_address_empty_group(self):
2193n/a address = self._test_get_x(parser.get_address,
2194n/a 'Monty Python:;',
2195n/a 'Monty Python:;',
2196n/a 'Monty Python:;',
2197n/a [],
2198n/a '')
2199n/a self.assertEqual(address.token_type, 'address')
2200n/a self.assertEqual(len(address.mailboxes), 0)
2201n/a self.assertEqual(address.mailboxes,
2202n/a address.all_mailboxes)
2203n/a self.assertEqual(address[0].token_type,
2204n/a 'group')
2205n/a self.assertEqual(address[0].display_name,
2206n/a 'Monty Python')
2207n/a
2208n/a def test_get_address_group(self):
2209n/a address = self._test_get_x(parser.get_address,
2210n/a 'Monty Python: x@example.com, y@example.com;',
2211n/a 'Monty Python: x@example.com, y@example.com;',
2212n/a 'Monty Python: x@example.com, y@example.com;',
2213n/a [],
2214n/a '')
2215n/a self.assertEqual(address.token_type, 'address')
2216n/a self.assertEqual(len(address.mailboxes), 2)
2217n/a self.assertEqual(address.mailboxes,
2218n/a address.all_mailboxes)
2219n/a self.assertEqual(address[0].token_type,
2220n/a 'group')
2221n/a self.assertEqual(address[0].display_name,
2222n/a 'Monty Python')
2223n/a self.assertEqual(address.mailboxes[0].local_part, 'x')
2224n/a
2225n/a def test_get_address_quoted_local_part(self):
2226n/a address = self._test_get_x(parser.get_address,
2227n/a '"foo bar"@example.com',
2228n/a '"foo bar"@example.com',
2229n/a '"foo bar"@example.com',
2230n/a [],
2231n/a '')
2232n/a self.assertEqual(address.token_type, 'address')
2233n/a self.assertEqual(len(address.mailboxes), 1)
2234n/a self.assertEqual(address.mailboxes,
2235n/a address.all_mailboxes)
2236n/a self.assertEqual(address.mailboxes[0].domain,
2237n/a 'example.com')
2238n/a self.assertEqual(address.mailboxes[0].local_part,
2239n/a 'foo bar')
2240n/a self.assertEqual(address[0].token_type, 'mailbox')
2241n/a
2242n/a def test_get_address_ends_at_special(self):
2243n/a address = self._test_get_x(parser.get_address,
2244n/a 'dinsdale@example.com, next',
2245n/a 'dinsdale@example.com',
2246n/a 'dinsdale@example.com',
2247n/a [],
2248n/a ', next')
2249n/a self.assertEqual(address.token_type, 'address')
2250n/a self.assertEqual(len(address.mailboxes), 1)
2251n/a self.assertEqual(address.mailboxes,
2252n/a address.all_mailboxes)
2253n/a self.assertEqual(address.mailboxes[0].domain,
2254n/a 'example.com')
2255n/a self.assertEqual(address[0].token_type, 'mailbox')
2256n/a
2257n/a def test_get_address_invalid_mailbox_invalid(self):
2258n/a address = self._test_get_x(parser.get_address,
2259n/a 'ping example.com, next',
2260n/a 'ping example.com',
2261n/a 'ping example.com',
2262n/a [errors.InvalidHeaderDefect, # addr-spec with no domain
2263n/a errors.InvalidHeaderDefect, # invalid local-part
2264n/a errors.InvalidHeaderDefect, # missing .s in local-part
2265n/a ],
2266n/a ', next')
2267n/a self.assertEqual(address.token_type, 'address')
2268n/a self.assertEqual(len(address.mailboxes), 0)
2269n/a self.assertEqual(len(address.all_mailboxes), 1)
2270n/a self.assertIsNone(address.all_mailboxes[0].domain)
2271n/a self.assertEqual(address.all_mailboxes[0].local_part, 'ping example.com')
2272n/a self.assertEqual(address[0].token_type, 'invalid-mailbox')
2273n/a
2274n/a def test_get_address_quoted_strings_in_atom_list(self):
2275n/a address = self._test_get_x(parser.get_address,
2276n/a '""example" example"@example.com',
2277n/a '""example" example"@example.com',
2278n/a 'example example@example.com',
2279n/a [errors.InvalidHeaderDefect]*3,
2280n/a '')
2281n/a self.assertEqual(address.all_mailboxes[0].local_part, 'example example')
2282n/a self.assertEqual(address.all_mailboxes[0].domain, 'example.com')
2283n/a self.assertEqual(address.all_mailboxes[0].addr_spec, '"example example"@example.com')
2284n/a
2285n/a
2286n/a # get_address_list
2287n/a
2288n/a def test_get_address_list_mailboxes_simple(self):
2289n/a address_list = self._test_get_x(parser.get_address_list,
2290n/a 'dinsdale@example.com',
2291n/a 'dinsdale@example.com',
2292n/a 'dinsdale@example.com',
2293n/a [],
2294n/a '')
2295n/a self.assertEqual(address_list.token_type, 'address-list')
2296n/a self.assertEqual(len(address_list.mailboxes), 1)
2297n/a self.assertEqual(address_list.mailboxes,
2298n/a address_list.all_mailboxes)
2299n/a self.assertEqual([str(x) for x in address_list.mailboxes],
2300n/a [str(x) for x in address_list.addresses])
2301n/a self.assertEqual(address_list.mailboxes[0].domain, 'example.com')
2302n/a self.assertEqual(address_list[0].token_type, 'address')
2303n/a self.assertIsNone(address_list[0].display_name)
2304n/a
2305n/a def test_get_address_list_mailboxes_two_simple(self):
2306n/a address_list = self._test_get_x(parser.get_address_list,
2307n/a 'foo@example.com, "Fred A. Bar" <bar@example.com>',
2308n/a 'foo@example.com, "Fred A. Bar" <bar@example.com>',
2309n/a 'foo@example.com, "Fred A. Bar" <bar@example.com>',
2310n/a [],
2311n/a '')
2312n/a self.assertEqual(address_list.token_type, 'address-list')
2313n/a self.assertEqual(len(address_list.mailboxes), 2)
2314n/a self.assertEqual(address_list.mailboxes,
2315n/a address_list.all_mailboxes)
2316n/a self.assertEqual([str(x) for x in address_list.mailboxes],
2317n/a [str(x) for x in address_list.addresses])
2318n/a self.assertEqual(address_list.mailboxes[0].local_part, 'foo')
2319n/a self.assertEqual(address_list.mailboxes[1].display_name, "Fred A. Bar")
2320n/a
2321n/a def test_get_address_list_mailboxes_complex(self):
2322n/a address_list = self._test_get_x(parser.get_address_list,
2323n/a ('"Roy A. Bear" <dinsdale@example.com>, '
2324n/a '(ping) Foo <x@example.com>,'
2325n/a 'Nobody Is. Special <y@(bird)example.(bad)com>'),
2326n/a ('"Roy A. Bear" <dinsdale@example.com>, '
2327n/a '(ping) Foo <x@example.com>,'
2328n/a 'Nobody Is. Special <y@(bird)example.(bad)com>'),
2329n/a ('"Roy A. Bear" <dinsdale@example.com>, '
2330n/a 'Foo <x@example.com>,'
2331n/a '"Nobody Is. Special" <y@example. com>'),
2332n/a [errors.ObsoleteHeaderDefect, # period in Is.
2333n/a errors.ObsoleteHeaderDefect], # cfws in domain
2334n/a '')
2335n/a self.assertEqual(address_list.token_type, 'address-list')
2336n/a self.assertEqual(len(address_list.mailboxes), 3)
2337n/a self.assertEqual(address_list.mailboxes,
2338n/a address_list.all_mailboxes)
2339n/a self.assertEqual([str(x) for x in address_list.mailboxes],
2340n/a [str(x) for x in address_list.addresses])
2341n/a self.assertEqual(address_list.mailboxes[0].domain, 'example.com')
2342n/a self.assertEqual(address_list.mailboxes[0].token_type, 'mailbox')
2343n/a self.assertEqual(address_list.addresses[0].token_type, 'address')
2344n/a self.assertEqual(address_list.mailboxes[1].local_part, 'x')
2345n/a self.assertEqual(address_list.mailboxes[2].display_name,
2346n/a 'Nobody Is. Special')
2347n/a
2348n/a def test_get_address_list_mailboxes_invalid_addresses(self):
2349n/a address_list = self._test_get_x(parser.get_address_list,
2350n/a ('"Roy A. Bear" <dinsdale@example.com>, '
2351n/a '(ping) Foo x@example.com[],'
2352n/a 'Nobody Is. Special <(bird)example.(bad)com>'),
2353n/a ('"Roy A. Bear" <dinsdale@example.com>, '
2354n/a '(ping) Foo x@example.com[],'
2355n/a 'Nobody Is. Special <(bird)example.(bad)com>'),
2356n/a ('"Roy A. Bear" <dinsdale@example.com>, '
2357n/a 'Foo x@example.com[],'
2358n/a '"Nobody Is. Special" < example. com>'),
2359n/a [errors.InvalidHeaderDefect, # invalid address in list
2360n/a errors.InvalidHeaderDefect, # 'Foo x' local part invalid.
2361n/a errors.InvalidHeaderDefect, # Missing . in 'Foo x' local part
2362n/a errors.ObsoleteHeaderDefect, # period in 'Is.' disp-name phrase
2363n/a errors.InvalidHeaderDefect, # no domain part in addr-spec
2364n/a errors.ObsoleteHeaderDefect], # addr-spec has comment in it
2365n/a '')
2366n/a self.assertEqual(address_list.token_type, 'address-list')
2367n/a self.assertEqual(len(address_list.mailboxes), 1)
2368n/a self.assertEqual(len(address_list.all_mailboxes), 3)
2369n/a self.assertEqual([str(x) for x in address_list.all_mailboxes],
2370n/a [str(x) for x in address_list.addresses])
2371n/a self.assertEqual(address_list.mailboxes[0].domain, 'example.com')
2372n/a self.assertEqual(address_list.mailboxes[0].token_type, 'mailbox')
2373n/a self.assertEqual(address_list.addresses[0].token_type, 'address')
2374n/a self.assertEqual(address_list.addresses[1].token_type, 'address')
2375n/a self.assertEqual(len(address_list.addresses[0].mailboxes), 1)
2376n/a self.assertEqual(len(address_list.addresses[1].mailboxes), 0)
2377n/a self.assertEqual(len(address_list.addresses[1].mailboxes), 0)
2378n/a self.assertEqual(
2379n/a address_list.addresses[1].all_mailboxes[0].local_part, 'Foo x')
2380n/a self.assertEqual(
2381n/a address_list.addresses[2].all_mailboxes[0].display_name,
2382n/a "Nobody Is. Special")
2383n/a
2384n/a def test_get_address_list_group_empty(self):
2385n/a address_list = self._test_get_x(parser.get_address_list,
2386n/a 'Monty Python: ;',
2387n/a 'Monty Python: ;',
2388n/a 'Monty Python: ;',
2389n/a [],
2390n/a '')
2391n/a self.assertEqual(address_list.token_type, 'address-list')
2392n/a self.assertEqual(len(address_list.mailboxes), 0)
2393n/a self.assertEqual(address_list.mailboxes,
2394n/a address_list.all_mailboxes)
2395n/a self.assertEqual(len(address_list.addresses), 1)
2396n/a self.assertEqual(address_list.addresses[0].token_type, 'address')
2397n/a self.assertEqual(address_list.addresses[0].display_name, 'Monty Python')
2398n/a self.assertEqual(len(address_list.addresses[0].mailboxes), 0)
2399n/a
2400n/a def test_get_address_list_group_simple(self):
2401n/a address_list = self._test_get_x(parser.get_address_list,
2402n/a 'Monty Python: dinsdale@example.com;',
2403n/a 'Monty Python: dinsdale@example.com;',
2404n/a 'Monty Python: dinsdale@example.com;',
2405n/a [],
2406n/a '')
2407n/a self.assertEqual(address_list.token_type, 'address-list')
2408n/a self.assertEqual(len(address_list.mailboxes), 1)
2409n/a self.assertEqual(address_list.mailboxes,
2410n/a address_list.all_mailboxes)
2411n/a self.assertEqual(address_list.mailboxes[0].domain, 'example.com')
2412n/a self.assertEqual(address_list.addresses[0].display_name,
2413n/a 'Monty Python')
2414n/a self.assertEqual(address_list.addresses[0].mailboxes[0].domain,
2415n/a 'example.com')
2416n/a
2417n/a def test_get_address_list_group_and_mailboxes(self):
2418n/a address_list = self._test_get_x(parser.get_address_list,
2419n/a ('Monty Python: dinsdale@example.com, "Fred" <flint@example.com>;, '
2420n/a 'Abe <x@example.com>, Bee <y@example.com>'),
2421n/a ('Monty Python: dinsdale@example.com, "Fred" <flint@example.com>;, '
2422n/a 'Abe <x@example.com>, Bee <y@example.com>'),
2423n/a ('Monty Python: dinsdale@example.com, "Fred" <flint@example.com>;, '
2424n/a 'Abe <x@example.com>, Bee <y@example.com>'),
2425n/a [],
2426n/a '')
2427n/a self.assertEqual(address_list.token_type, 'address-list')
2428n/a self.assertEqual(len(address_list.mailboxes), 4)
2429n/a self.assertEqual(address_list.mailboxes,
2430n/a address_list.all_mailboxes)
2431n/a self.assertEqual(len(address_list.addresses), 3)
2432n/a self.assertEqual(address_list.mailboxes[0].local_part, 'dinsdale')
2433n/a self.assertEqual(address_list.addresses[0].display_name,
2434n/a 'Monty Python')
2435n/a self.assertEqual(address_list.addresses[0].mailboxes[0].domain,
2436n/a 'example.com')
2437n/a self.assertEqual(address_list.addresses[0].mailboxes[1].local_part,
2438n/a 'flint')
2439n/a self.assertEqual(address_list.addresses[1].mailboxes[0].local_part,
2440n/a 'x')
2441n/a self.assertEqual(address_list.addresses[2].mailboxes[0].local_part,
2442n/a 'y')
2443n/a self.assertEqual(str(address_list.addresses[1]),
2444n/a str(address_list.mailboxes[2]))
2445n/a
2446n/a def test_invalid_content_disposition(self):
2447n/a content_disp = self._test_parse_x(
2448n/a parser.parse_content_disposition_header,
2449n/a ";attachment", "; attachment", ";attachment",
2450n/a [errors.InvalidHeaderDefect]*2
2451n/a )
2452n/a
2453n/a def test_invalid_content_transfer_encoding(self):
2454n/a cte = self._test_parse_x(
2455n/a parser.parse_content_transfer_encoding_header,
2456n/a ";foo", ";foo", ";foo", [errors.InvalidHeaderDefect]*3
2457n/a )
2458n/a
2459n/a
2460n/a@parameterize
2461n/aclass Test_parse_mime_parameters(TestParserMixin, TestEmailBase):
2462n/a
2463n/a def mime_parameters_as_value(self,
2464n/a value,
2465n/a tl_str,
2466n/a tl_value,
2467n/a params,
2468n/a defects):
2469n/a mime_parameters = self._test_parse_x(parser.parse_mime_parameters,
2470n/a value, tl_str, tl_value, defects)
2471n/a self.assertEqual(mime_parameters.token_type, 'mime-parameters')
2472n/a self.assertEqual(list(mime_parameters.params), params)
2473n/a
2474n/a
2475n/a mime_parameters_params = {
2476n/a
2477n/a 'simple': (
2478n/a 'filename="abc.py"',
2479n/a ' filename="abc.py"',
2480n/a 'filename=abc.py',
2481n/a [('filename', 'abc.py')],
2482n/a []),
2483n/a
2484n/a 'multiple_keys': (
2485n/a 'filename="abc.py"; xyz=abc',
2486n/a ' filename="abc.py"; xyz="abc"',
2487n/a 'filename=abc.py; xyz=abc',
2488n/a [('filename', 'abc.py'), ('xyz', 'abc')],
2489n/a []),
2490n/a
2491n/a 'split_value': (
2492n/a "filename*0*=iso-8859-1''%32%30%31%2E; filename*1*=%74%69%66",
2493n/a ' filename="201.tif"',
2494n/a "filename*0*=iso-8859-1''%32%30%31%2E; filename*1*=%74%69%66",
2495n/a [('filename', '201.tif')],
2496n/a []),
2497n/a
2498n/a # Note that it is undefined what we should do for error recovery when
2499n/a # there are duplicate parameter names or duplicate parts in a split
2500n/a # part. We choose to ignore all duplicate parameters after the first
2501n/a # and to take duplicate or missing rfc 2231 parts in appearance order.
2502n/a # This is backward compatible with get_param's behavior, but the
2503n/a # decisions are arbitrary.
2504n/a
2505n/a 'duplicate_key': (
2506n/a 'filename=abc.gif; filename=def.tiff',
2507n/a ' filename="abc.gif"',
2508n/a "filename=abc.gif; filename=def.tiff",
2509n/a [('filename', 'abc.gif')],
2510n/a [errors.InvalidHeaderDefect]),
2511n/a
2512n/a 'duplicate_key_with_split_value': (
2513n/a "filename*0*=iso-8859-1''%32%30%31%2E; filename*1*=%74%69%66;"
2514n/a " filename=abc.gif",
2515n/a ' filename="201.tif"',
2516n/a "filename*0*=iso-8859-1''%32%30%31%2E; filename*1*=%74%69%66;"
2517n/a " filename=abc.gif",
2518n/a [('filename', '201.tif')],
2519n/a [errors.InvalidHeaderDefect]),
2520n/a
2521n/a 'duplicate_key_with_split_value_other_order': (
2522n/a "filename=abc.gif; "
2523n/a " filename*0*=iso-8859-1''%32%30%31%2E; filename*1*=%74%69%66",
2524n/a ' filename="abc.gif"',
2525n/a "filename=abc.gif;"
2526n/a " filename*0*=iso-8859-1''%32%30%31%2E; filename*1*=%74%69%66",
2527n/a [('filename', 'abc.gif')],
2528n/a [errors.InvalidHeaderDefect]),
2529n/a
2530n/a 'duplicate_in_split_value': (
2531n/a "filename*0*=iso-8859-1''%32%30%31%2E; filename*1*=%74%69%66;"
2532n/a " filename*1*=abc.gif",
2533n/a ' filename="201.tifabc.gif"',
2534n/a "filename*0*=iso-8859-1''%32%30%31%2E; filename*1*=%74%69%66;"
2535n/a " filename*1*=abc.gif",
2536n/a [('filename', '201.tifabc.gif')],
2537n/a [errors.InvalidHeaderDefect]),
2538n/a
2539n/a 'missing_split_value': (
2540n/a "filename*0*=iso-8859-1''%32%30%31%2E; filename*3*=%74%69%66;",
2541n/a ' filename="201.tif"',
2542n/a "filename*0*=iso-8859-1''%32%30%31%2E; filename*3*=%74%69%66;",
2543n/a [('filename', '201.tif')],
2544n/a [errors.InvalidHeaderDefect]),
2545n/a
2546n/a 'duplicate_and_missing_split_value': (
2547n/a "filename*0*=iso-8859-1''%32%30%31%2E; filename*3*=%74%69%66;"
2548n/a " filename*3*=abc.gif",
2549n/a ' filename="201.tifabc.gif"',
2550n/a "filename*0*=iso-8859-1''%32%30%31%2E; filename*3*=%74%69%66;"
2551n/a " filename*3*=abc.gif",
2552n/a [('filename', '201.tifabc.gif')],
2553n/a [errors.InvalidHeaderDefect]*2),
2554n/a
2555n/a # Here we depart from get_param and assume the *0* was missing.
2556n/a 'duplicate_with_broken_split_value': (
2557n/a "filename=abc.gif; "
2558n/a " filename*2*=iso-8859-1''%32%30%31%2E; filename*3*=%74%69%66",
2559n/a ' filename="abc.gif201.tif"',
2560n/a "filename=abc.gif;"
2561n/a " filename*2*=iso-8859-1''%32%30%31%2E; filename*3*=%74%69%66",
2562n/a [('filename', 'abc.gif201.tif')],
2563n/a # Defects are apparent missing *0*, and two 'out of sequence'.
2564n/a [errors.InvalidHeaderDefect]*3),
2565n/a
2566n/a }
2567n/a
2568n/a@parameterize
2569n/aclass Test_parse_mime_version(TestParserMixin, TestEmailBase):
2570n/a
2571n/a def mime_version_as_value(self,
2572n/a value,
2573n/a tl_str,
2574n/a tl_value,
2575n/a major,
2576n/a minor,
2577n/a defects):
2578n/a mime_version = self._test_parse_x(parser.parse_mime_version,
2579n/a value, tl_str, tl_value, defects)
2580n/a self.assertEqual(mime_version.major, major)
2581n/a self.assertEqual(mime_version.minor, minor)
2582n/a
2583n/a mime_version_params = {
2584n/a
2585n/a 'rfc_2045_1': (
2586n/a '1.0',
2587n/a '1.0',
2588n/a '1.0',
2589n/a 1,
2590n/a 0,
2591n/a []),
2592n/a
2593n/a 'RFC_2045_2': (
2594n/a '1.0 (produced by MetaSend Vx.x)',
2595n/a '1.0 (produced by MetaSend Vx.x)',
2596n/a '1.0 ',
2597n/a 1,
2598n/a 0,
2599n/a []),
2600n/a
2601n/a 'RFC_2045_3': (
2602n/a '(produced by MetaSend Vx.x) 1.0',
2603n/a '(produced by MetaSend Vx.x) 1.0',
2604n/a ' 1.0',
2605n/a 1,
2606n/a 0,
2607n/a []),
2608n/a
2609n/a 'RFC_2045_4': (
2610n/a '1.(produced by MetaSend Vx.x)0',
2611n/a '1.(produced by MetaSend Vx.x)0',
2612n/a '1. 0',
2613n/a 1,
2614n/a 0,
2615n/a []),
2616n/a
2617n/a 'empty': (
2618n/a '',
2619n/a '',
2620n/a '',
2621n/a None,
2622n/a None,
2623n/a [errors.HeaderMissingRequiredValue]),
2624n/a
2625n/a }
2626n/a
2627n/a
2628n/a
2629n/aclass TestFolding(TestEmailBase):
2630n/a
2631n/a policy = policy.default
2632n/a
2633n/a def _test(self, tl, folded, policy=policy):
2634n/a self.assertEqual(tl.fold(policy=policy), folded, tl.ppstr())
2635n/a
2636n/a def test_simple_unstructured_no_folds(self):
2637n/a self._test(parser.get_unstructured("This is a test"),
2638n/a "This is a test\n")
2639n/a
2640n/a def test_simple_unstructured_folded(self):
2641n/a self._test(parser.get_unstructured("This is also a test, but this "
2642n/a "time there are enough words (and even some "
2643n/a "symbols) to make it wrap; at least in theory."),
2644n/a "This is also a test, but this time there are enough "
2645n/a "words (and even some\n"
2646n/a " symbols) to make it wrap; at least in theory.\n")
2647n/a
2648n/a def test_unstructured_with_unicode_no_folds(self):
2649n/a self._test(parser.get_unstructured("hübsch kleiner beißt"),
2650n/a "=?utf-8?q?h=C3=BCbsch_kleiner_bei=C3=9Ft?=\n")
2651n/a
2652n/a def test_one_ew_on_each_of_two_wrapped_lines(self):
2653n/a self._test(parser.get_unstructured("Mein kleiner Kaktus ist sehr "
2654n/a "hübsch. Es hat viele Stacheln "
2655n/a "und oft beißt mich."),
2656n/a "Mein kleiner Kaktus ist sehr =?utf-8?q?h=C3=BCbsch=2E?= "
2657n/a "Es hat viele Stacheln\n"
2658n/a " und oft =?utf-8?q?bei=C3=9Ft?= mich.\n")
2659n/a
2660n/a def test_ews_combined_before_wrap(self):
2661n/a self._test(parser.get_unstructured("Mein Kaktus ist hübsch. "
2662n/a "Es beißt mich. "
2663n/a "And that's all I'm sayin."),
2664n/a "Mein Kaktus ist =?utf-8?q?h=C3=BCbsch=2E__Es_bei=C3=9Ft?= "
2665n/a "mich. And that's\n"
2666n/a " all I'm sayin.\n")
2667n/a
2668n/a # XXX Need test of an encoded word so long that it needs to be wrapped
2669n/a
2670n/a def test_simple_address(self):
2671n/a self._test(parser.get_address_list("abc <xyz@example.com>")[0],
2672n/a "abc <xyz@example.com>\n")
2673n/a
2674n/a def test_address_list_folding_at_commas(self):
2675n/a self._test(parser.get_address_list('abc <xyz@example.com>, '
2676n/a '"Fred Blunt" <sharp@example.com>, '
2677n/a '"J.P.Cool" <hot@example.com>, '
2678n/a '"K<>y" <key@example.com>, '
2679n/a 'Firesale <cheap@example.com>, '
2680n/a '<end@example.com>')[0],
2681n/a 'abc <xyz@example.com>, "Fred Blunt" <sharp@example.com>,\n'
2682n/a ' "J.P.Cool" <hot@example.com>, "K<>y" <key@example.com>,\n'
2683n/a ' Firesale <cheap@example.com>, <end@example.com>\n')
2684n/a
2685n/a def test_address_list_with_unicode_names(self):
2686n/a self._test(parser.get_address_list(
2687n/a 'Hübsch Kaktus <beautiful@example.com>, '
2688n/a 'beißt beißt <biter@example.com>')[0],
2689n/a '=?utf-8?q?H=C3=BCbsch?= Kaktus <beautiful@example.com>,\n'
2690n/a ' =?utf-8?q?bei=C3=9Ft_bei=C3=9Ft?= <biter@example.com>\n')
2691n/a
2692n/a def test_address_list_with_unicode_names_in_quotes(self):
2693n/a self._test(parser.get_address_list(
2694n/a '"Hübsch Kaktus" <beautiful@example.com>, '
2695n/a '"beißt" beißt <biter@example.com>')[0],
2696n/a '=?utf-8?q?H=C3=BCbsch?= Kaktus <beautiful@example.com>,\n'
2697n/a ' =?utf-8?q?bei=C3=9Ft_bei=C3=9Ft?= <biter@example.com>\n')
2698n/a
2699n/a # XXX Need tests with comments on various sides of a unicode token,
2700n/a # and with unicode tokens in the comments. Spaces inside the quotes
2701n/a # currently don't do the right thing.
2702n/a
2703n/a def test_initial_whitespace_splitting(self):
2704n/a body = parser.get_unstructured(' ' + 'x'*77)
2705n/a header = parser.Header([
2706n/a parser.HeaderLabel([parser.ValueTerminal('test:', 'atext')]),
2707n/a parser.CFWSList([parser.WhiteSpaceTerminal(' ', 'fws')]), body])
2708n/a self._test(header, 'test: \n ' + 'x'*77 + '\n')
2709n/a
2710n/a def test_whitespace_splitting(self):
2711n/a self._test(parser.get_unstructured('xxx ' + 'y'*77),
2712n/a 'xxx \n ' + 'y'*77 + '\n')
2713n/a
2714n/aif __name__ == '__main__':
2715n/a unittest.main()