diff options
Diffstat (limited to 'test/lisp/mail')
-rw-r--r-- | test/lisp/mail/flow-fill-tests.el | 107 | ||||
-rw-r--r-- | test/lisp/mail/footnote-tests.el | 47 | ||||
-rw-r--r-- | test/lisp/mail/ietf-drums-date-tests.el | 172 | ||||
-rw-r--r-- | test/lisp/mail/ietf-drums-tests.el | 178 | ||||
-rw-r--r-- | test/lisp/mail/mail-extr-tests.el | 41 | ||||
-rw-r--r-- | test/lisp/mail/mail-parse-tests.el | 54 | ||||
-rw-r--r-- | test/lisp/mail/mail-utils-tests.el | 105 | ||||
-rw-r--r-- | test/lisp/mail/qp-tests.el | 74 | ||||
-rw-r--r-- | test/lisp/mail/rfc2045-tests.el | 37 | ||||
-rw-r--r-- | test/lisp/mail/rfc2047-tests.el | 60 | ||||
-rw-r--r-- | test/lisp/mail/rfc6068-tests.el | 52 | ||||
-rw-r--r-- | test/lisp/mail/rfc822-tests.el | 83 | ||||
-rw-r--r-- | test/lisp/mail/rmail-tests.el | 6 | ||||
-rw-r--r-- | test/lisp/mail/rmailmm-tests.el | 117 | ||||
-rw-r--r-- | test/lisp/mail/undigest-tests.el | 359 | ||||
-rw-r--r-- | test/lisp/mail/uudecode-resources/uudecoded.txt | 16 | ||||
-rw-r--r-- | test/lisp/mail/uudecode-resources/uuencoded.txt | 19 | ||||
-rw-r--r-- | test/lisp/mail/uudecode-tests.el | 75 |
18 files changed, 1599 insertions, 3 deletions
diff --git a/test/lisp/mail/flow-fill-tests.el b/test/lisp/mail/flow-fill-tests.el new file mode 100644 index 00000000000..8436a9627a8 --- /dev/null +++ b/test/lisp/mail/flow-fill-tests.el @@ -0,0 +1,107 @@ +;;; flow-fill-tests.el --- Tests for flow-fill.el -*- lexical-binding: t -*- + +;; Copyright (C) 2019-2022 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;;; Code: + +(require 'ert) +(require 'flow-fill) + +(ert-deftest fill-flow-tests-fill-flowed-decode () + (let ((input + (concat + "> Thou villainous ill-breeding spongy dizzy-eyed \n" + "> reeky elf-skinned pigeon-egg! \n" + ">> Thou artless swag-bellied milk-livered \n" + ">> dismal-dreaming idle-headed scut!\n" + ">>> Thou errant folly-fallen spleeny reeling-ripe \n" + ">>> unmuzzled ratsbane!\n" + ">>>> Henceforth, the coding style is to be strictly \n" + ">>>> enforced, including the use of only upper case.\n" + ">>>>> I've noticed a lack of adherence to \n" + ">>>>> the coding \n" + ">>>>> styles, of late.\n" + ">>>>>> Any complaints?\n")) + (output + (concat + "> Thou villainous ill-breeding spongy dizzy-eyed reeky elf-skinned\n" + "> pigeon-egg! \n" + ">> Thou artless swag-bellied milk-livered dismal-dreaming idle-headed\n" + ">> scut!\n" + ">>> Thou errant folly-fallen spleeny reeling-ripe unmuzzled ratsbane!\n" + ">>>> Henceforth, the coding style is to be strictly enforced,\n" + ">>>> including the use of only upper case.\n" + ">>>>> I've noticed a lack of adherence to the coding styles, of late.\n" + ">>>>>> Any complaints?\n")) + (fill-flowed-display-column 69)) + (with-temp-buffer + (insert input) + (fill-flowed) + (message "foo") + (should (equal (buffer-string) output))))) + +(ert-deftest fill-flow-tests-fill-flowed-encode () + (let ((input + (concat + "> Thou villainous ill-breeding spongy dizzy-eyed \n" + "> reeky elf-skinned pigeon-egg! \n" + ">> Thou artless swag-bellied milk-livered \n" + ">> dismal-dreaming idle-headed scut!\n" + ">>> Thou errant folly-fallen spleeny reeling-ripe \n" + ">>> unmuzzled ratsbane!\n" + ">>>> Henceforth, the coding style is to be strictly \n" + ">>>> enforced, including the use of only upper case.\n" + ">>>>> I've noticed a lack of adherence to the coding \n" + ">>>>> styles, of late.\n" + ">>>>>> Any complaints?\n")) + (output + (concat + "> Thou villainous ill-breeding spongy dizzy-eyed \n" + "> reeky elf-skinned pigeon-egg! \n" + ">> Thou artless swag-bellied milk-livered \n" + ">> dismal-dreaming idle-headed scut!\n" + ">>> Thou errant folly-fallen spleeny reeling-ripe \n" + ">>> unmuzzled ratsbane!\n" + ">>>> Henceforth, the coding style is to be strictly \n" + ">>>> enforced, including the use of only upper case.\n" + ">>>>> I've noticed a lack of adherence to the coding \n" + ">>>>> styles, of late.\n" + ">>>>>> Any complaints?\n")) + (fill-flowed-display-column 69)) + (with-temp-buffer + (insert input) + (fill-flowed-encode) + (should (equal (buffer-string) output))))) + +(ert-deftest fill-flow-tests-fill-flowed-stuffed () + (let ((input + (concat + " > From space-stuffed with a \n" + "continuation.\n")) + (output + "> From space-stuffed with a continuation.\n") + (fill-flowed-display-column 69)) + (with-temp-buffer + (insert input) + (fill-flowed) + (should (equal (buffer-string) output))))) + +(provide 'flow-fill-tests) +;;; flow-fill-tests.el ends here diff --git a/test/lisp/mail/footnote-tests.el b/test/lisp/mail/footnote-tests.el new file mode 100644 index 00000000000..f3a35e3dfc6 --- /dev/null +++ b/test/lisp/mail/footnote-tests.el @@ -0,0 +1,47 @@ +;;; footnote-tests.el --- Tests for footnote-mode -*- lexical-binding: t; -*- + +;; Copyright (C) 2019-2022 Free Software Foundation, Inc. + +;; Author: Stefan Monnier <monnier@iro.umontreal.ca> +;; Keywords: + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. + +;;; Code: + +(require 'footnote) + +(ert-deftest footnote-tests-same-place () + (with-temp-buffer + (footnote-mode 1) + (insert "hello world") + (beginning-of-line) (forward-word) + (footnote-add-footnote) + (insert "footnote") + (footnote-back-to-message) + (should (equal (buffer-substring (point-min) (point)) + "hello[1]")) + (beginning-of-line) (forward-word) + (footnote-add-footnote) + (insert "other footnote") + (footnote-back-to-message) + (should (equal (buffer-substring (point-min) (point)) + "hello[1]")) + (should (equal (buffer-substring (point-min) (pos-eol)) + "hello[1][2] world")))) + +(provide 'footnote-tests) +;;; footnote-tests.el ends here diff --git a/test/lisp/mail/ietf-drums-date-tests.el b/test/lisp/mail/ietf-drums-date-tests.el new file mode 100644 index 00000000000..781d72d3529 --- /dev/null +++ b/test/lisp/mail/ietf-drums-date-tests.el @@ -0,0 +1,172 @@ +;;; ietf-drums-date-tests.el --- Test suite for ietf-drums-date.el -*- lexical-binding:t -*- + +;; Copyright (C) 2022 Free Software Foundation, Inc. + +;; Author: Bob Rogers <rogers@rgrjr.com> + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;;; Code: + +(require 'ert) +(require 'ietf-drums) +(require 'ietf-drums-date) + +(ert-deftest ietf-drums-date-tests () + "Test basic ietf-drums-parse-date-string functionality." + + ;; Test tokenization. + (should (equal (ietf-drums-date--tokenize-string " ") '())) + (should (equal (ietf-drums-date--tokenize-string " a b") '("a" "b"))) + (should (equal (ietf-drums-date--tokenize-string "a bbc dde") + '("a" "bbc" "dde"))) + (should (equal (ietf-drums-date--tokenize-string " , a 27 b,, c 14:32 ") + '("a" 27 "b" "c" "14:32"))) + ;; Some folding whitespace tests. + (should (equal (ietf-drums-date--tokenize-string " a b (end) c" t) + '("a" "b"))) + (should (equal (ietf-drums-date--tokenize-string "(quux)a (foo (bar)) b(baz)") + '("a" "b"))) + (should (equal (ietf-drums-date--tokenize-string "a b\\cde") + ;; Strictly incorrect, but strictly unnecessary syntax. + '("a" "b\\cde"))) + (should (equal (ietf-drums-date--tokenize-string "a b\\ de") + '("a" "b\\ de"))) + (should (equal (ietf-drums-date--tokenize-string "a \\de \\(f") + '("a" "\\de" "\\(f"))) + + ;; Start with some compatible RFC822 dates. + (dolist (case '(("Mon, 22 Feb 2016 19:35:42 +0100" + (42 35 19 22 2 2016 1 -1 3600)) + ("22 Feb 2016 19:35:42 +0100" + (42 35 19 22 2 2016 nil -1 3600)) + ("Mon, 22 February 2016 19:35:42 +0100" + (42 35 19 22 2 2016 1 -1 3600)) + ("Mon, 22 feb 2016 19:35:42 +0100" + (42 35 19 22 2 2016 1 -1 3600)) + ("Monday, 22 february 2016 19:35:42 +0100" + (42 35 19 22 2 2016 1 -1 3600)) + ("Monday, 22 february 2016 19:35:42 PST" + (42 35 19 22 2 2016 1 nil -28800)) + ("Friday, 21 Sep 2018 13:47:58 PDT" + (58 47 13 21 9 2018 5 t -25200)) + ("Friday, 21 Sep 2018 13:47:58 EDT" + (58 47 13 21 9 2018 5 t -14400)) + ("Mon, 22 Feb 2016 19:35:42" + (42 35 19 22 2 2016 1 -1 nil)) + ("Friday, 21 Sep 2018 13:47:58" + (58 47 13 21 9 2018 5 -1 nil)))) + (let* ((input (car case)) + (parsed (cadr case))) + ;; The input should parse the same without RFC822. + (should (equal (ietf-drums-parse-date-string input) parsed)) + (should (equal (ietf-drums-parse-date-string input nil t) parsed)) + ;; Check the encoded date (the official output, though the + ;; decoded-time is easier to debug). + (should (time-equal-p (ietf-drums-parse-date input) + (encode-time parsed))))) + + ;; Two-digit years are not allowed by the "modern" format. + (should (equal (ietf-drums-parse-date-string "22 Feb 16 19:35:42 +0100") + '(42 35 19 22 2 2016 nil -1 3600))) + (should (equal (ietf-drums-parse-date-string "22 Feb 16 19:35:42 +0100" nil t) + '(nil nil nil 22 2 nil nil -1 nil))) + (should (equal (should-error (ietf-drums-parse-date-string + "22 Feb 16 19:35:42 +0100" t t)) + '(date-parse-error "Four-digit years are required" 16))) + (should (equal (ietf-drums-parse-date-string "22 Feb 96 19:35:42 +0100") + '(42 35 19 22 2 1996 nil -1 3600))) + (should (equal (ietf-drums-parse-date-string "22 Feb 96 19:35:42 +0100" nil t) + '(nil nil nil 22 2 nil nil -1 nil))) + (should (equal (should-error (ietf-drums-parse-date-string + "22 Feb 96 19:35:42 +0100" t t)) + '(date-parse-error "Four-digit years are required" 96))) + + ;; Try some dates with comments. + (should (equal (ietf-drums-parse-date-string + "22 Feb (today) 16 19:35:42 +0100") + '(42 35 19 22 2 2016 nil -1 3600))) + (should (equal (ietf-drums-parse-date-string + "22 Feb (today) 16 19:35:42 +0100" nil t) + '(nil nil nil 22 2 nil nil -1 nil))) + (should (equal (should-error (ietf-drums-parse-date-string + "22 Feb (today) 16 19:35:42 +0100" t t)) + '(date-parse-error "Expected a year" nil))) + (should (equal (ietf-drums-parse-date-string + "22 Feb 96 (long ago) 19:35:42 +0100") + '(42 35 19 22 2 1996 nil -1 3600))) + (should (equal (ietf-drums-parse-date-string + "Friday, 21 Sep(comment \\) with \\( parens)18 19:35:42") + '(42 35 19 21 9 2018 5 -1 nil))) + (should (equal (ietf-drums-parse-date-string + "Friday, 21 Sep 18 19:35:42 (unterminated comment") + '(42 35 19 21 9 2018 5 -1 nil))) + + ;; Test some RFC822 error cases + (dolist (test '(("33 1 2022" ("Slot out of range" day 33 1 31)) + ("0 1 2022" ("Slot out of range" day 0 1 31)) + ("1 1 2020 2021" ("Expected an alphabetic month" 1)) + ("1 Jan 2020 2021" ("Expected a time" 2021)) + ("1 Jan 2020 20:21 2000" ("Expected a timezone" 2000)) + ("1 Jan 2020 20:21 +0200 33" ("Extra token(s)" 33)))) + (should (equal (should-error (ietf-drums-parse-date-string (car test) t)) + (cons 'date-parse-error (cadr test))))) + + (dolist (test '(("22 Feb 196" nil ;; bad year + ("Four-digit years are required" 196)) + ("22 Feb 16 19:35:24" t ;; two-digit year + ("Four-digit years are required" 16)) + ("22 Feb 96 19:35:42" t ;; two-digit year + ("Four-digit years are required" 96)) + ("2 Feb 2021 1996" nil + ("Expected a time" 1996)) + ("22 Fub 1996" nil + ("Expected an alphabetic month" "fub")) + ("1 Jan 2020 30" nil + ("Expected a time" 30)) + ("1 Jan 2020 16:47 15:15" nil + ("Expected a timezone" "15:15")) + ("1 Jan 2020 16:47 +0800 -0800" t + ("Extra token(s)" "-0800")) + ;; Range tests + ("32 Dec 2021" nil + ("Slot out of range" day 32 1 31)) + ("0 Dec 2021" nil + ("Slot out of range" day 0 1 31)) + ("3 13 2021" nil + ("Expected an alphabetic month" 13)) + ("3 Dec 0000" t + ("Four-digit years are required" 0)) + ("3 Dec 20021" nil + ("Slot out of range" year 20021 1 9999)) + ("1 Jan 2020 24:21:14" nil + ("Slot out of range" hour "24:21:14" 0 23)) + ("1 Jan 2020 14:60:21" nil + ("Slot out of range" minute "14:60:21" 0 59)) + ("1 Jan 2020 14:21:61" nil + ("Slot out of range" second "14:21:61" 0 60)))) + (should (equal (should-error + (ietf-drums-parse-date-string (car test) t (cadr test))) + (cons 'date-parse-error (caddr test))))) + (should (equal (ietf-drums-parse-date-string + "1 Jan 2020 14:21:60") ;; a leap second! + '(60 21 14 1 1 2020 nil -1 nil)))) + +(provide 'ietf-drums-date-tests) + +;;; ietf-drums-date-tests.el ends here diff --git a/test/lisp/mail/ietf-drums-tests.el b/test/lisp/mail/ietf-drums-tests.el new file mode 100644 index 00000000000..b13937bf736 --- /dev/null +++ b/test/lisp/mail/ietf-drums-tests.el @@ -0,0 +1,178 @@ +;;; ietf-drums-tests.el --- Test suite for ietf-drums.el -*- lexical-binding:t -*- + +;; Copyright (C) 2022 Free Software Foundation, Inc. + +;; Author: Bob Rogers <rogers@rgrjr.com> + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;;; Code: + +(require 'ert) +(require 'ietf-drums) + +(ert-deftest ietf-drums-tests () + "Test ietf-drums functionality." + + ;; ietf-drums-remove-comments + (should (equal (ietf-drums-remove-comments "random string") "random string")) + (should (equal (ietf-drums-remove-comments "random \"non comment\" string") + "random \"non comment\" string")) + (should (equal (ietf-drums-remove-comments "random (comment) string") + "random string")) + (should (equal (ietf-drums-remove-comments "random (comment) (string)") + "random ")) + (should (equal (ietf-drums-remove-comments + "random (first) (second (and)) (third) not fourth") + "random not fourth")) + ;; Test some unterminated comments. + (should (equal (ietf-drums-remove-comments "test an (unterminated comment") + "test an ")) + (should (equal (ietf-drums-remove-comments "test an \"unterminated quote") + ;; returns the string unchanged (and doesn't barf). + "test an \"unterminated quote")) + (should (equal (ietf-drums-remove-comments + ;; note that double-quote is not special. + "test (unterminated comments with \"quoted (\" )stuff") + "test ")) + + ;; ietf-drums-remove-whitespace + (should (equal (ietf-drums-remove-whitespace "random string") + "randomstring")) + (should (equal (ietf-drums-remove-whitespace "random (comment) string") + "random(comment)string")) + (should (equal (ietf-drums-remove-whitespace "random \"non comment\" string") + "random\"non comment\"string")) + (should (equal (ietf-drums-remove-whitespace "random (comment)\r\n(string)") + "random(comment)(string)")) + (should (equal (ietf-drums-remove-whitespace + "random (first) (second (and)) (third) not fourth") + "random(first)(second (and))(third)notfourth")) + ;; Test some unterminated comments and quotes. + (should (equal (ietf-drums-remove-whitespace + "random (first) (second (and)) (third unterminated") + "random(first)(second (and))(third unterminated")) + (should (equal (ietf-drums-remove-whitespace "random \"non terminated string") + "random\"non terminated string")) + + ;; ietf-drums-strip + (should (equal (ietf-drums-strip "random string") "randomstring")) + (should (equal (ietf-drums-strip "random \"non comment\" string") + "random\"non comment\"string")) + (should (equal (ietf-drums-strip "random (comment) string") + "randomstring")) + (should (equal (ietf-drums-strip "random (comment) (string)") + "random")) + (should (equal (ietf-drums-strip + "random (first) (second (and)) (third) not fourth") + "randomnotfourth")) + + ;; ietf-drums-strip-cte + (should (equal (ietf-drums-strip-cte "random \"non comment\" string") + ;; [the " " is still in there because it was quoted + ;; through the "strip". -- rgr, 5-Feb-22.] + "randomnon commentstring")) + (should (equal (ietf-drums-strip-cte "ran(d)do<m@>[s;t:r],,in=g") + "randomstring")) + + ;; ietf-drums-quote-string + (should (equal (ietf-drums-quote-string "Bob") "Bob")) + (should (equal (ietf-drums-quote-string "Foo Bar") "\"Foo Bar\"")) + + ;; ietf-drums-get-comment + (should (equal (ietf-drums-get-comment "random string") nil)) + (should (equal (ietf-drums-get-comment "random (comment) string") "comment")) + (should (equal (ietf-drums-get-comment "random \"non comment\" string") nil)) + (should (equal (ietf-drums-get-comment "\"still (non) comment\" string") + nil)) + (should (equal (ietf-drums-get-comment "random (comment)\r\nstring") + "comment")) + (should (equal (ietf-drums-get-comment "random (comment) (string)") "string")) + (should (equal (ietf-drums-get-comment + "random (first) (second (and)) (third) not fourth") + "third")) + + ;; ietf-drums-make-address + (should (equal (ietf-drums-make-address "Bob Rogers" "rogers@rgrjr.com") + "\"Bob Rogers\" <rogers@rgrjr.com>")) + (should (equal (ietf-drums-make-address nil "rogers@rgrjr.com") + "rogers@rgrjr.com")) + + ;; ietf-drums-parse-address + (should (equal (ietf-drums-parse-address "foo@example.com") + '("foo@example.com"))) + (should (equal (ietf-drums-parse-address "<foo@example.com>") + '("foo@example.com"))) + (should (equal (ietf-drums-parse-address "'foo' <foo@example.com>") + '("foo@example.com" . "'foo'"))) + (should (equal (ietf-drums-parse-address "foo <foo@example.com>") + '("foo@example.com" . "foo"))) + (should (equal (ietf-drums-parse-address "foo <foo@example.com> bar") + ;; [contrary to RFC2822, which wants the display-name + ;; before the address. -- rgr, 5-Feb-22.] + '("foo@example.com" . "foo bar"))) + (should (equal (ietf-drums-parse-address " <foo@example.com> foo ") + ;; [ditto. -- rgr, 5-Feb-22.] + '("foo@example.com" . "foo"))) + (should (equal (ietf-drums-parse-address "foo@example.com (foo)") + '("foo@example.com" . "foo"))) + (should (equal (ietf-drums-parse-address "Bar Baz <barbaz@example.com>") + '("barbaz@example.com" . "Bar Baz"))) + (should (equal (ietf-drums-parse-address "barbaz@example.com (Bar Baz)") + '("barbaz@example.com" . "Bar Baz"))) + (should (equal (ietf-drums-parse-address + "Bar Baz (ignored) <barbaz@example.com>") + '("barbaz@example.com" . "Bar Baz"))) + (should (equal (ietf-drums-parse-address "<barbaz@example.com> Bar Baz") + '("barbaz@example.com" . "Bar Baz"))) + (should (equal (ietf-drums-parse-address + "(Bar Baz not ignored) barbaz@example.com") + ;; [not strictly RFC2822, which expects the name + ;; comment after the address. -- rgr, 5-Feb-22.] + '("barbaz@example.com" . "Bar Baz not ignored"))) + (should (equal (ietf-drums-parse-address + "(ignored) <barbaz@example.com> (Bar Baz not ignored)") + '("barbaz@example.com" . "Bar Baz not ignored"))) + (should (equal (ietf-drums-parse-address + "(ignored) barbaz@example.com (Bar Baz not ignored)") + '("barbaz@example.com" . "Bar Baz not ignored"))) + ;; Test for RFC2047 token decoding. + (should (equal (ietf-drums-parse-address + "=?utf-8?B?0JfQtNGA0LDMgdCy0YHRgtCy0YPQudGC0LUh?= <foo@goo.ru>" + t) + '("foo@goo.ru" . "Здра́вствуйте!"))) + + ;; ietf-drums-parse-addresses + ;; Note that it's not worth getting too elaborate here, as the heavy + ;; lifting is all done by ietf-drums-parse-address. + (should (equal (ietf-drums-parse-addresses "foo@example.com") + '(("foo@example.com")))) + (should (equal (ietf-drums-parse-addresses + "foo@example.com, bar@example.com") + '(("foo@example.com") ("bar@example.com")))) + (should (equal (ietf-drums-parse-addresses + "foo@example.com, quux, bar@example.com") + '(("foo@example.com") ("bar@example.com")))) + (should (equal (ietf-drums-parse-addresses + "foo@example.com, Quux Dude <quux@noop.org>, bar@example.com") + '(("foo@example.com") ("quux@noop.org" . "Quux Dude") + ("bar@example.com"))))) + +(provide 'ietf-drums-tests) + +;;; ietf-drums-tests.el ends here diff --git a/test/lisp/mail/mail-extr-tests.el b/test/lisp/mail/mail-extr-tests.el new file mode 100644 index 00000000000..a8f0c605cb0 --- /dev/null +++ b/test/lisp/mail/mail-extr-tests.el @@ -0,0 +1,41 @@ +;;; mail-extr-tests.el --- Tests for mail-extr.el -*- lexical-binding: t -*- + +;; Copyright (C) 2022 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;;; Code: + +(require 'ert) +(require 'mail-extr) + +(defconst mail-extract-test-cases + '(("foo@example.org" . (nil "foo@example.org")) + ("J. Random Hacker <foo@example.org>" . ("J. Random Hacker" "foo@example.org")) + ("\"J. Random Hacker\" <foo@example.org>" . ("J. Random Hacker" "foo@example.org")) + ("Ååå Äää <foo@example.org>" . ("Ååå Äää" "foo@example.org")))) + +(ert-deftest mail-extract-address-components () + (dolist (test mail-extract-test-cases) + (should (equal (mail-extract-address-components (car test)) (cdr test))))) + +(ert-deftest what-domain () + (should (equal (what-domain "cu") "CU: Cuba"))) + +(provide 'mail-extr-tests) +;;; mail-extr-tests.el ends here diff --git a/test/lisp/mail/mail-parse-tests.el b/test/lisp/mail/mail-parse-tests.el new file mode 100644 index 00000000000..f5e6f1fb034 --- /dev/null +++ b/test/lisp/mail/mail-parse-tests.el @@ -0,0 +1,54 @@ +;;; mail-parse-tests.el --- tests for mail-parse.el -*- lexical-binding: t -*- + +;; Copyright (C) 2021-2022 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;;; Code: + +(require 'ert) +(require 'mail-parse) +(require 'subr-x) + +(ert-deftest test-mail-header-parse-address-lax () + (should (equal (mail-header-parse-address-lax + "Lars Ingebrigtsen <larsi@gnus.org>") + '("larsi@gnus.org" . "Lars Ingebrigtsen"))) + (should (equal (mail-header-parse-address-lax + "Lars Ingebrigtsen larsi@gnus.org>") + '("larsi@gnus.org" . "Lars Ingebrigtsen"))) + (should (equal (mail-header-parse-address-lax + "Lars Ingebrigtsen larsi@gnus.org") + '("larsi@gnus.org" . "Lars Ingebrigtsen"))) + (should (equal (mail-header-parse-address-lax + "larsi@gnus.org (Lars Ingebrigtsen)") + '("larsi@gnus.org " . "Lars Ingebrigtsen"))) + (should (equal (mail-header-parse-address-lax "larsi@gnus.org") + '("larsi@gnus.org"))) + (should (equal (mail-header-parse-address-lax "foo") + nil))) + +(ert-deftest test-mail-header-parse-addresses-lax () + (should (equal (mail-header-parse-addresses-lax + "Bob Weiner <rsw@gnu.org>, Mats Lidell <matsl@gnu.org>") + '(("rsw@gnu.org" . "Bob Weiner") + ("matsl@gnu.org" . "Mats Lidell"))))) + +(provide 'mail-parse-tests) + +;;; mail-parse-tests.el ends here diff --git a/test/lisp/mail/mail-utils-tests.el b/test/lisp/mail/mail-utils-tests.el new file mode 100644 index 00000000000..29a9b9eeb96 --- /dev/null +++ b/test/lisp/mail/mail-utils-tests.el @@ -0,0 +1,105 @@ +;;; mail-utils-tests.el --- tests for mail-utils.el -*- lexical-binding: t -*- + +;; Copyright (C) 2021-2022 Free Software Foundation, Inc. + +;; Author: Stefan Kangas <stefankangas@gmail.com> + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;;; Code: + +(require 'ert) +(require 'sasl) +(require 'mail-utils) + +(ert-deftest mail-utils-tests-mail-quote-printable () + (should (equal (mail-quote-printable "abc") "abc")) + (should (equal (mail-quote-printable "åäö") "=E5=E4=F6")) + (should (equal (mail-quote-printable "åäö" t) "=?ISO-8859-1?Q?=E5=E4=F6?="))) + +(ert-deftest mail-utils-tests-mail-quote-printable-region () + (with-temp-buffer + (insert "?=\"\"") + (mail-quote-printable-region (point-min) (point-max)) + (should (equal (buffer-string) "=3F=3D=22=22"))) + (with-temp-buffer + (insert "x") + (mail-quote-printable-region (point-min) (point-max) t) + (should (equal (buffer-string) "=?=?ISO-8859-1?Q?x")))) + +(ert-deftest mail-utils-tests-mail-unquote-printable () + (should (equal (mail-unquote-printable "=E5=E4=F6") "åäö")) + (should (equal (mail-unquote-printable "=?ISO-8859-1?Q?=E5=E4=F6?=" t) "åäö"))) + +(ert-deftest mail-utils-tests-mail-unquote-printable-region () + (with-temp-buffer + (insert "=E5=E4=F6") + (mail-unquote-printable-region (point-min) (point-max)) + (should (equal (buffer-string) "åäö"))) + (with-temp-buffer + (insert "=?ISO-8859-1?Q?=E5=E4=F6?=") + (mail-unquote-printable-region (point-min) (point-max) t) + (should (equal (buffer-string) "åäö")))) + +(ert-deftest mail-utils-tests-mail-strip-quoted-names () + (should (equal (mail-strip-quoted-names + "\"foo\" <foo@example.org>, bar@example.org") + "foo@example.org, bar@example.org"))) + +(ert-deftest mail-utils-tests-mail-dont-reply-to () + (let ((mail-dont-reply-to-names "foo@example.org")) + (should (equal (mail-dont-reply-to "foo@example.org, bar@example.org") + "bar@example.org")))) + + +(ert-deftest mail-utils-tests-mail-fetch-field () + (with-temp-buffer + (insert "Foo: bar\nBaz: zut") + (should (equal (mail-fetch-field "Foo") "bar")))) + +(ert-deftest mail-utils-tests-mail-parse-comma-list () + (with-temp-buffer + (insert "foo@example.org,bar@example.org,baz@example.org") + (goto-char (point-min)) + (should (equal (mail-parse-comma-list) + '("baz@example.org" "bar@example.org" "foo@example.org"))))) + +(ert-deftest mail-utils-tests-mail-comma-list-regexp () + (should (equal (mail-comma-list-regexp + "foo@example.org,bar@example.org,baz@example.org") + "foo@example.org\\|bar@example.org\\|baz@example.org"))) + +(ert-deftest mail-utils-tests-mail-rfc822-time-zone () + (with-suppressed-warnings ((obsolete mail-rfc822-time-zone)) + (should (stringp (mail-rfc822-time-zone (current-time)))))) + +(ert-deftest mail-utils-test-mail-rfc822-date/contains-year () + (should (string-match (rx " 20" digit digit " ") + (mail-rfc822-date)))) + +(ert-deftest mail-utils-test-mail-mbox-from () + (with-temp-buffer + (insert "Subject: Hello +From: jrh@example.org +To: emacs-devel@gnu.org +Date: Sun, 07 Feb 2021 22:46:37 -0500") + (should (equal (mail-mbox-from) + "From jrh@example.org Sun Feb 7 22:46:37 2021\n")))) + +(provide 'mail-utils-tests) +;;; mail-utils-tests.el ends here diff --git a/test/lisp/mail/qp-tests.el b/test/lisp/mail/qp-tests.el new file mode 100644 index 00000000000..e8e58063b9c --- /dev/null +++ b/test/lisp/mail/qp-tests.el @@ -0,0 +1,74 @@ +;;; qp-tests.el --- Tests for qp.el -*- lexical-binding:t; coding:utf-8 -*- + +;; Copyright (C) 2020-2022 Free Software Foundation, Inc. + +;; Author: Stefan Kangas <stefankangas@gmail.com> + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;;; Code: + +(require 'ert) +(require 'qp) + +;; Quote by Antoine de Saint-Exupéry, Citadelle (1948) +;; from https://en.wikipedia.org/wiki/Quoted-printable +(defvar qp-tests-quote-qp + (concat "J'interdis aux marchands de vanter trop leurs marchandises. Car ils se font =\n" + "vite p=C3=A9dagogues et t'enseignent comme but ce qui n'est par essence qu'=\n" + "un moyen, et te trompant ainsi sur la route =C3=A0 suivre les voil=C3=A0 bi=\n" + "ent=C3=B4t qui te d=C3=A9gradent, car si leur musique est vulgaire ils te f=\n" + "abriquent pour te la vendre une =C3=A2me vulgaire.")) +(defvar qp-tests-quote-utf8 + (concat "J'interdis aux marchands de vanter trop leurs marchandises. Car ils se font " + "vite pédagogues et t'enseignent comme but ce qui n'est par essence qu'" + "un moyen, et te trompant ainsi sur la route à suivre les voilà bi" + "entôt qui te dégradent, car si leur musique est vulgaire ils te f" + "abriquent pour te la vendre une âme vulgaire.")) + +(ert-deftest qp-test--quoted-printable-decode-region () + (with-temp-buffer + (insert qp-tests-quote-qp) + (encode-coding-region (point-min) (point-max) 'utf-8) + (quoted-printable-decode-region (point-min) (point-max) 'utf-8) + (should (equal (buffer-string) qp-tests-quote-utf8)))) + +(ert-deftest qp-test--quoted-printable-decode-string () + (should (equal (quoted-printable-decode-string "foo!") "foo!")) + (should (equal (quoted-printable-decode-string "=0C") "\^L")) + (should (equal (quoted-printable-decode-string "=3D") "=")) + (should (equal (quoted-printable-decode-string "=A1Hola, se=F1or!?") + "\241Hola, se\361or!?"))) + +(ert-deftest qp-test--quoted-printable-encode-region () + (with-temp-buffer + (insert (make-string 26 ?=)) + ;; (encode-coding-region (point-min) (point-max) 'utf-8) + (quoted-printable-encode-region (point-min) (point-max) t) + (should (equal (buffer-string) + (concat "=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D" + "=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=\n=3D"))))) + +(ert-deftest qp-test--quoted-printable-encode-string () + (should (equal (quoted-printable-encode-string "\241Hola, se\361or!?") + "=A1Hola, se=F1or!?")) + ;; Multibyte character. + (should-error (quoted-printable-encode-string "å"))) + +(provide 'qp-tests) +;;; qp-tests.el ends here diff --git a/test/lisp/mail/rfc2045-tests.el b/test/lisp/mail/rfc2045-tests.el new file mode 100644 index 00000000000..c65a0011c70 --- /dev/null +++ b/test/lisp/mail/rfc2045-tests.el @@ -0,0 +1,37 @@ +;;; rfc2045-tests.el --- Tests for rfc2045.el -*- lexical-binding:t -*- + +;; Copyright (C) 2020-2022 Free Software Foundation, Inc. + +;; Author: Stefan Kangas <stefankangas@gmail.com> + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;;; Code: + +(require 'ert) +(require 'rfc2045) + +(ert-deftest rfc2045-test-encode-string () + (should (equal (rfc2045-encode-string "foo" "bar") "foo=bar")) + (should (equal (rfc2045-encode-string "foo" "bar-baz") "foo=bar-baz")) + (should (equal (rfc2045-encode-string "foo" "bar baz") "foo=\"bar baz\"")) + (should (equal (rfc2045-encode-string "foo" "bar\tbaz") "foo=\"bar\tbaz\"")) + (should (equal (rfc2045-encode-string "foo" "bar\nbaz") "foo=\"bar\nbaz\""))) + +(provide 'rfc2045-tests) +;;; rfc2045-tests.el ends here diff --git a/test/lisp/mail/rfc2047-tests.el b/test/lisp/mail/rfc2047-tests.el new file mode 100644 index 00000000000..6e50ce2f320 --- /dev/null +++ b/test/lisp/mail/rfc2047-tests.el @@ -0,0 +1,60 @@ +;;; rfc2047-tests.el --- tests for rfc2047.el -*- lexical-binding: t -*- + +;; Copyright (C) 2019-2022 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. + +;;; Code: + +(require 'ert) +(require 'rfc2047) + +(defun test-rfc2047 (before after) + (with-temp-buffer + (insert before) + (goto-char (point-min)) + (rfc2047-fold-field) + (should (equal (buffer-string) after)))) + +(ert-deftest test-rfc2047-fold-short () + (test-rfc2047 + "Organization: Lots Of Short Words Here Lots Of Short Words Here Lots Of Short Words Here\n" + + "Organization: Lots Of Short Words Here Lots Of Short Words Here Lots Of + Short Words Here +")) + +(ert-deftest test-rfc2047-fold-encoded () + (test-rfc2047 + "Subject: This is =?utf-8?Q?=C3=A1?= long subject that's =?utf-8?Q?v=C3=A9ry?= long and =?utf-8?Q?ver=C3=BD?= encoded yes indeed it =?utf-8?Q?=C3=ADs?=\n" + "Subject: This is =?utf-8?Q?=C3=A1?= long subject that's + =?utf-8?Q?v=C3=A9ry?= long and =?utf-8?Q?ver=C3=BD?= encoded yes indeed it + =?utf-8?Q?=C3=ADs?= +")) + +(ert-deftest test-rfc2047-fold-long () + (test-rfc2047 + "Organization: verylongverylongverylongverylongverylongverylongverylongverylongverylongword and then\n" + "Organization: verylongverylongverylongverylongverylongverylongverylongverylongverylongword + and then +")) + +(ert-deftest test-rfc2047-fold-long-short () + (test-rfc2047 + "Organization: verylongverylongverylongverylongverylongverylongverylongverylongverylongword\n" + "Organization: verylongverylongverylongverylongverylongverylongverylongverylongverylongword\n")) + +;;; rfc2047-tests.el ends here diff --git a/test/lisp/mail/rfc6068-tests.el b/test/lisp/mail/rfc6068-tests.el new file mode 100644 index 00000000000..0efbb68cc2f --- /dev/null +++ b/test/lisp/mail/rfc6068-tests.el @@ -0,0 +1,52 @@ +;;; rfc6068-tests.el --- Tests for rfc6068.el -*- lexical-binding:t -*- + +;; Copyright (C) 2020-2022 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;;; Code: + +(require 'ert) +(require 'rfc6068) + +(ert-deftest rfc6068-unhexify-string () + (should (equal (rfc6068-unhexify-string "hello%20there") "hello there")) + (should (equal (rfc6068-unhexify-string "caf%C3%A9") "café"))) + +(ert-deftest rfc6068-parse-mailto-url () + (should + (equal + (rfc6068-parse-mailto-url "mailto:foo@example.org?subject=Foo&bar=baz") + '(("To" . "foo@example.org") ("Subject" . "Foo") ("Bar" . "baz")))) + (should + (equal + (rfc6068-parse-mailto-url "mailto:foo@bar.com?to=bar@example.org") + '(("To" . "foo@bar.com, bar@example.org")))) + (should + (equal (rfc6068-parse-mailto-url "mailto:foo@bar.com?subject=bar%20baz") + '(("To" . "foo@bar.com") ("Subject" . "bar baz")))) + (should + (equal (rfc6068-parse-mailto-url "mailto:foo@bar.com?subject=bar%20baz&to=other@bar.com") + '(("Subject" . "bar baz") ("To" . "foo@bar.com, other@bar.com")))) + (should + (equal (rfc6068-parse-mailto-url "mailto:user@example.org?subject=caf%C3%A9&body=caf%C3%A9") + '(("To" . "user@example.org") ("Subject" . "café") ("Body" . "café"))))) + +(provide 'rfc6068-tests) + +;;; rfc6068-tests.el ends here diff --git a/test/lisp/mail/rfc822-tests.el b/test/lisp/mail/rfc822-tests.el new file mode 100644 index 00000000000..ff29dac4277 --- /dev/null +++ b/test/lisp/mail/rfc822-tests.el @@ -0,0 +1,83 @@ +;;; rfc822-tests.el --- Tests for rfc822.el -*- lexical-binding:t -*- + +;; Copyright (C) 2020-2022 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;;; Code: + +(require 'ert) +(require 'rfc822) + +(defmacro rfc822-tests-deftest (email desc &optional valid) + `(ert-deftest ,(intern (format "rfc822-email-%s-%s" + (if valid "valid" "invalid") + desc)) () + (if ,valid + (should (equal (rfc822-addresses ,email) (list ,email))) + (let ((addresses (rfc822-addresses ,email))) + ;; `rfc822-addresses' returns a string if parsing fails. + (while (and (consp addresses) + (not (eq (string-to-char (car addresses)) ?\())) + (setq addresses (cdr addresses))) + ;; Found saved error. + (should (= (length addresses) 1)))))) + +;;;; Valid emails + +(rfc822-tests-deftest "email@example.org" "email" t) +(rfc822-tests-deftest "firstname.lastname@example.org" "dot-in-address" t) +(rfc822-tests-deftest "email@subdomain.example.org" "dot-in-subdomain" t) +(rfc822-tests-deftest "firstname+lastname@example.org" "contains-plus-sign" t) +(rfc822-tests-deftest "email@123.123.123.123" "domain-valid-ip" t) +(rfc822-tests-deftest "email@[123.123.123.123]" "domain-valid-ip-square-bracket" t) +(rfc822-tests-deftest "\"email\"@example.org" "quotes-around-email" t) +(rfc822-tests-deftest "1234567890@example.org" "digits-in-address" t) +(rfc822-tests-deftest "email@example-one.com" "dash-in-domain-name" t) +(rfc822-tests-deftest "_______@example.org" "underscore-in-address" t) +(rfc822-tests-deftest "email@example.name" "dotname-tld" t) +(rfc822-tests-deftest "email@example.co.jp" "dot-in-tld" t) +(rfc822-tests-deftest "firstname-lastname@example.org" "dash-in-address" t) +(rfc822-tests-deftest "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghiklm@example.org" "address-long" t) + +;;;; Invalid emails + +(rfc822-tests-deftest "#@%^%#$@#$@#.com" "garbage") +(rfc822-tests-deftest "@example.org" "missing-username") +(rfc822-tests-deftest "email@example@example.org" "two-at-signs") +(rfc822-tests-deftest ".email@example.org" "address-leading-dot") +(rfc822-tests-deftest "email.@example.org" "address-trailing-dot") +(rfc822-tests-deftest "email..email@example.org" "address-multiple-dots") +(rfc822-tests-deftest "email@example..org" "domain-multiple-dots") +(rfc822-tests-deftest "email@example.org." "domain-trailing-dot") +(rfc822-tests-deftest "email@.example.org" "domain-leading-dot") +(rfc822-tests-deftest "test\\@test@example.org" "address-escaped-at-sign") + +;; FIXME: Should these fail? +;; (rfc822-tests-deftest "plainaddress" "missing-at-sign-and-domain") +;; (rfc822-tests-deftest "email@example.org (J. Random Hacker)" "text-following-email") +;; (rfc822-tests-deftest "email@-example.org" "leading-dash-in-domain-is-invalid") +;; (rfc822-tests-deftest "email@example-.org" "trailing-dash-in-domain-is-invalid") +;; (rfc822-tests-deftest "あいうえお@example.org" "address-unicode-chars") +;; (rfc822-tests-deftest "email.example.org" "missing-at") +;; (rfc822-tests-deftest "email@111.222.333.44444" "invalid-IP-format") +;; (rfc822-tests-deftest "email@domain" "missing-top-level-domain") +;; (rfc822-tests-deftest "email@domain.web" ".web-is-not-a-valid-top-level-domain") + +(provide 'rfc822-tests) +;;; rfc822-tests.el ends here diff --git a/test/lisp/mail/rmail-tests.el b/test/lisp/mail/rmail-tests.el index b0b86764226..44394cd52ed 100644 --- a/test/lisp/mail/rmail-tests.el +++ b/test/lisp/mail/rmail-tests.el @@ -1,6 +1,6 @@ ;;; rmail-tests.el --- Test suite. -*- lexical-binding: t -*- -;; Copyright (C) 2015-2017 Free Software Foundation, Inc. +;; Copyright (C) 2015-2022 Free Software Foundation, Inc. ;; This file is part of GNU Emacs. @@ -23,7 +23,7 @@ (ert-deftest rmail-autoload () - "Tests to see whether reftex-auc has been autoloaded" + "Test that `rmail-edit-current-message' has been autoloaded." (should (fboundp 'rmail-edit-current-message)) (should @@ -32,4 +32,4 @@ 'rmail-edit-current-message)))) (provide 'rmail-tests) -;; rmail-tests.el ends here +;;; rmail-tests.el ends here diff --git a/test/lisp/mail/rmailmm-tests.el b/test/lisp/mail/rmailmm-tests.el new file mode 100644 index 00000000000..5d1ac6d6306 --- /dev/null +++ b/test/lisp/mail/rmailmm-tests.el @@ -0,0 +1,117 @@ +;;; rmailmm-tests.el --- Tests for rmailmm.el -*- lexical-binding:t -*- + +;; Copyright (C) 2006-2022 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Converted to ert from previous manual tests. + +;; FIXME: Some of these still lack a condition for success. + +;;; Code: + +(require 'ert) +(require 'rmailmm) + +(ert-deftest rmailmm-test-handler () + "Test of a mail using no MIME parts at all." + (let ((mail "To: alex@gnu.org +Content-Type: text/plain; charset=koi8-r +Content-Transfer-Encoding: 8bit +MIME-Version: 1.0 + +\372\304\322\301\327\323\324\327\325\312\324\305\41") + (correct "To: alex@gnu.org +Content-Type: text/plain; charset=koi8-r +Content-Transfer-Encoding: 8bit +MIME-Version: 1.0 + +Здравствуйте! +")) + (with-temp-buffer + (erase-buffer) + (set-buffer-multibyte nil) + (insert mail) + (rmail-mime-show t) + (set-buffer-multibyte t) + (should (equal (buffer-string) correct))))) + +;;;; FIXME: This doesn't seem to be working. +(ert-deftest rmailmm-test-bulk-handler () + "Test of a mail used as an example in RFC 2183." + :tags '(:unstable) + (let ((mail "Content-Type: image/jpeg +Content-Disposition: attachment; filename=genome.jpeg; + modification-date=\"Wed, 12 Feb 1997 16:29:51 -0500\"; +Content-Description: a complete map of the human genome +Content-Transfer-Encoding: base64 + +iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAABGdBTUEAALGPC/xhBQAAAAZQ +TFRF////AAAAVcLTfgAAAPZJREFUeNq9ldsOwzAIQ+3//+l1WlvA5ZLsoUiTto4TB+ISoAjy ++ITfRBfcAmgRFFeAm+J6uhdKdFhFWUgDkFsK0oUp/9G2//Kj7Jx+5tSKOdBscgUYiKHRS/me +WATQdRUvAK0Bnmshmtn79PpaLBbbOZkjKvRnjRZoRswOkG1wFchKew2g9wXVJVZL/m4+B+vv +9AxQQR2Q33SgAYJzzVACdAWjAfRYzYFO9n6SLnydtQHSMxYDMAKqZ/8FS/lTK+zuq3CtK64L +UDwbgUEAUmk2Zyg101d6PhCDySgAvTvDgKiuOrc4dLxUb7UMnhGIexyI+d6U+ABuNAP4Simx +lgAAAABJRU5ErkJggg== +")) + (with-temp-buffer + (erase-buffer) + (insert mail) + (rmail-mime-show) + ;; FIXME: What is the condition for success? + ))) + +;; FIXME: Has no condition for success -- see below. +(ert-deftest rmailmm-test-multipart-handler () + "Test of a mail used as an example in RFC 2046." + :tags '(:unstable) + (let ((mail "From: Nathaniel Borenstein <nsb@bellcore.com> +To: Ned Freed <ned@innosoft.com> +Date: Sun, 21 Mar 1993 23:56:48 -0800 (PST) +Subject: Sample message +MIME-Version: 1.0 +Content-type: multipart/mixed; boundary=\"simple boundary\" + +This is the preamble. It is to be ignored, though it +is a handy place for composition agents to include an +explanatory note to non-MIME conformant readers. + +--simple boundary + +This is implicitly typed plain US-ASCII text. +It does NOT end with a linebreak. +--simple boundary +Content-type: text/plain; charset=us-ascii + +This is explicitly typed plain US-ASCII text. +It DOES end with a linebreak. + +--simple boundary-- + +This is the epilogue. It is also to be ignored.")) + (switch-to-buffer (get-buffer-create "*test*")) + (erase-buffer) + (insert mail) + (rmail-mime-show t) + ;; FIXME: What is the condition for success? + (should nil) ; expected fail for now + )) + +(provide 'rmailmm-tests) + +;;; rmailmm-tests.el ends here diff --git a/test/lisp/mail/undigest-tests.el b/test/lisp/mail/undigest-tests.el new file mode 100644 index 00000000000..d52c9f9c5ab --- /dev/null +++ b/test/lisp/mail/undigest-tests.el @@ -0,0 +1,359 @@ +;;; undigest-tests.el --- Tests for undigest.el -*- lexical-binding:t -*- + +;; Copyright (C) 2022 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. + +;;; Code: + +(require 'ert) +(require 'ert-x) +(require 'rmail) +(require 'undigest) + +;;; Variables: +;; Some digests for testing. +(defvar rmail-rfc934-digest "From tester Fri Jan 24 00:00:00 2022 +From: Digester <digester@digester.com> +To: Undigester <undigester@undigester.com> +Date: ddd, dd mmm yy hh:mm:ss zzz +Subject: Testing you + +Testing the undigester. + +------- Message sep + +From: NN1 <nn1@nn1.com> +To: Digester <digester@digester.com> +Date: ddd, dd mmm yy hh:mm:ss zzz +Subject: Message one + +This is message one. + +------- Message sep + +From: NN2 <nn2@nn2.com> +To: Digester <digester@digester.com> +Date: ddd, dd mmm yy hh:mm:ss zzz +Subject: Message two + +This is message two. +" + + "RFC 934 digest.") + +(defvar rmail-rfc1153-digest-strict "From tester Fri Jan 24 00:00:00 2022 +Date: ddd, dd mmm yy hh:mm:ss zzz +From: Digester <digester@digester.com> +To: Undigester <undigester@undigester.com> +Date: ddd, dd mmm yy hh:mm:ss zzz +Subject: Testing you + +Some mailing list information. + +Today's Topics: + + 1. Message One Subject (Sender) + 2. Message Two Subject (Sender) + +---------------------------------------------------------------------- + +Date: ddd, dd mmm yy hh:mm:ss zzz +From: NN1 <nn1@nn1.com> +Subject: Message One Subject + +This is message one. + +------------------------------ + +Date: ddd, dd mmm yy hh:mm:ss zzz +From: NN2 <nn2@nn2.com> +Subject: Message Two Subject + +This is message two. + +------------------------------ + +End of Digest. +************************************ +" + "RFC 1153 strict style digest.") + +(defvar rmail-rfc1153-digest-less-strict "From tester Fri Jan 24 00:00:00 2022 +From: Digester <digester@digester.com> +To: Undigester <undigester@undigester.com> +Date: ddd, dd mmm yy hh:mm:ss zzz +Subject: Testing you + +Some mailing list information. + +Today's Topics: + + 1. Message One Subject (Sender) + 2. Message Two Subject (Sender) + +---------------------------------------------------------------------- + +Date: ddd, dd mmm yy hh:mm:ss zzz +From: NN1 <nn1@nn1.com> +Subject: Message One Subject + +This is message one. + +------------------------------ + +Date: ddd, dd mmm yy hh:mm:ss zzz +From: NN2 <nn2@nn2.com> +Subject: Message Two Subject + +This is message two. + +------------------------------ + +Subject: Digest Footer + +End of Sbcl-help Digest, Vol 158, Issue 4 +***************************************** +" + "RFC 1153 style digest, with a Subject header.") + +(defvar rmail-rfc1153-digest-sloppy "From tester Fri Jan 24 00:00:00 2022 +From: Digester <digester@digester.com> +To: Undigester <undigester@undigester.com> +Date: ddd, dd mmm yy hh:mm:ss zzz +Subject: Testing you + +Some mailing list information. + +Today's Topics: + + 1. Message One Subject (Sender) + 2. Message Two Subject (Sender) + +---------------------------------------------------------------------- + +Date: ddd, dd mmm yy hh:mm:ss zzz +From: NN1 <nn1@nn1.com> +Subject: Message One Subject + +This is message one. + +------------------------------ + +Date: ddd, dd mmm yy hh:mm:ss zzz +From: NN2 <nn2@nn2.com> +Subject: Message Two Subject + +This is message two. + +------------------------------ + +Subject: Digest Footer + +______________________________________________ +Some blurb. + +End of Digest. +************************************ +" + "RFC 1153 sloppy style digest.") + +(defvar rmail-rfc1521-mime-digest "From tester Fri Jan 24 00:00:00 2022 +From: Digester <digester@digester.com> +To: Undigester <undigester@undigester.com> +Date: ddd, dd mmm yy hh:mm:ss zzz +Subject: Test digest +MIME-Version: 1.0 +Content-Type: multipart/digest; boundary=\"----- =_aaaaaaaaaa0\" + +------- =_aaaaaaaaaa0 +Content-Type: message/rfc822 + +From: NN1 <nn1@nn1.com> +To: Digester <digester@digester.com> +Date: ddd, dd mmm yy hh:mm:ss zzz +Subject: Message one + +Message one. + +------- =_aaaaaaaaaa0 + +From: NN2 <nn2@nn2.com> +To: Digester <digester@digester.com> +Date: ddd, dd mmm yy hh:mm:ss zzz +Subject: Message two + +Message two. + +------- =_aaaaaaaaaa0 +" + "RFC 1521 style MIME digest.") + +(defvar rmail-multipart-mixed-digest + "From tester Fri Jan 24 00:00:00 2022 +From: Digester <digester@digester.com> +To: Undigester <undigester@undigester.com> +Date: ddd, dd mmm yy hh:mm:ss zzz +Subject: Test digest +Content-Type: multipart/mixed; boundary=\"===============2529375068597856000==\" +MIME-Version: 1.0 + +--===============2529375068597856000== +Content-Type: text/plain; +MIME-Version: 1.0 +Content-Description: Today's Topics + +Some message. + +--===============2529375068597856000== +Content-Type: multipart/digest; boundary=\"===============6060050777038710134==\" +MIME-Version: 1.0 + +--===============6060050777038710134== +Content-Type: message/rfc822 +MIME-Version: 1.0 + +From: NN1 <nn1@nn1.com> +To: Digester <digester@digester.com> +Date: ddd, dd mmm yy hh:mm:ss zzz +Subject: Message one + +Message one. + +--===============6060050777038710134== +Content-Type: message/rfc822 +MIME-Version: 1.0 + +From: NN2 <nn2@nn2.com> +To: Digester <digester@digester.com> +Date: ddd, dd mmm yy hh:mm:ss zzz +Subject: Message two + +Message two. + +--===============6060050777038710134==-- + +--===============2529375068597856000== +Content-Type: text/plain; +MIME-Version: 1.0 +Content-Description: Digest Footer + +The footer. + +--===============2529375068597856000==--" + "RFC 1521 digest inside a multipart/mixed message.") + +;;; Utils: +(defun rmail-message-content (message) + "Return the content of the message numbered MESSAGE." + (rmail-show-message message) + (let ((beg (rmail-msgbeg rmail-current-message)) + (end (rmail-msgend rmail-current-message))) + (with-current-buffer rmail-view-buffer + (save-excursion + (goto-char beg) + (search-forward "\n\n" end nil) + (buffer-substring-no-properties (match-end 0) end))))) + +;;; Tests: +(ert-deftest rmail-undigest-test-rfc934-digest () + "Test that we can undigest a RFC 934 digest." + (ert-with-temp-file file + :text rmail-rfc934-digest + ;; Rmail reads mbox files literally, so we must make sure the + ;; temporary mbox file has Unix-style EOLs. + :coding 'undecided-unix + (rmail file) + (undigestify-rmail-message) + (should (= rmail-total-messages 4)) + (should (string= (rmail-message-content 2) "Testing the undigester.\n\n")) + (should (string= (rmail-message-content 3) "This is message one.\n\n")) + (should (string= (rmail-message-content 4) "This is message two.\n")))) + +(ert-deftest rmail-undigest-test-rfc1153-digest-strict () + "Test that we can undigest a strict RFC 1153 digest." + :expected-result :failed + (ert-with-temp-file file + :text rmail-rfc1153-digest-strict + ;; Rmail reads mbox files literally, so we must make sure the + ;; temporary mbox file has Unix-style EOLs. + :coding 'undecided-unix + (rmail file) + (should + (ignore-errors + ;; This throws an error, because the Trailer is not recognized + ;; as a valid RFC 822 (or later) message. + (undigestify-rmail-message) + (should (string= (rmail-message-content 2) "Testing the undigester.\n\n")) + (should (string= (rmail-message-content 3) "This is message one.\n\n")) + (should (string= (rmail-message-content 4) "This is message two.\n")) + t)))) + +(ert-deftest rmail-undigest-test-rfc1153-less-strict-digest () + "Test that we can undigest a RFC 1153 with a Subject header in its footer." + (ert-with-temp-file file + :text rmail-rfc1153-digest-less-strict + ;; Rmail reads mbox files literally, so we must make sure the + ;; temporary mbox file has Unix-style EOLs. + :coding 'undecided-unix + (rmail file) + (undigestify-rmail-message) + (should (= rmail-total-messages 5)) + (should (string= (rmail-message-content 3) "This is message one.\n\n")) + (should (string= (rmail-message-content 4) "This is message two.\n\n")))) + +(ert-deftest rmail-undigest-test-rfc1153-sloppy-digest () + "Test that we can undigest a sloppy RFC 1153 digest." + (ert-with-temp-file file + :text rmail-rfc1153-digest-sloppy + ;; Rmail reads mbox files literally, so we must make sure the + ;; temporary mbox file has Unix-style EOLs. + :coding 'undecided-unix + (rmail file) + (undigestify-rmail-message) + (should (= rmail-total-messages 5)) + (should (string= (rmail-message-content 3) "This is message one.\n\n")) + (should (string= (rmail-message-content 4) "This is message two.\n\n")))) + +;; This fails because `rmail-digest-parse-mime' combines the preamble with the +;; first message of the digest. And then, it doesn't get rid of the last +;; separator. +(ert-deftest rmail-undigest-test-rfc1521-mime-digest () + "Test that we can undigest a RFC 1521 MIME digest." + :expected-result :failed + (ert-with-temp-file file + :text rmail-rfc1521-mime-digest + ;; Rmail reads mbox files literally, so we must make sure the + ;; temporary mbox file has Unix-style EOLs. + :coding 'undecided-unix + (rmail file) + (undigestify-rmail-message) + (should (= rmail-total-messages 3)) + (should (string= (rmail-message-content 2) "Message one.\n\n")) + (should (string= (rmail-message-content 3) "Message two.\n\n")))) + +(ert-deftest rmail-undigest-test-multipart-mixed-digest () + "Test that we can undigest a digest inside a multipart/mixed digest." + (ert-with-temp-file file + :text rmail-multipart-mixed-digest + ;; Rmail reads mbox files literally, so we must make sure the + ;; temporary mbox file has Unix-style EOLs. + :coding 'undecided-unix + (rmail file) + (undigestify-rmail-message) + (should (= rmail-total-messages 4)) + (should (string= (rmail-message-content 2) "Message one.\n\n")) + (should (string= (rmail-message-content 3) "Message two.\n\n")))) diff --git a/test/lisp/mail/uudecode-resources/uudecoded.txt b/test/lisp/mail/uudecode-resources/uudecoded.txt new file mode 100644 index 00000000000..a6f75519a17 --- /dev/null +++ b/test/lisp/mail/uudecode-resources/uudecoded.txt @@ -0,0 +1,16 @@ +This is a test file encoded with uuencode. + +This file is part of GNU Emacs. + +GNU Emacs is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +GNU Emacs is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. diff --git a/test/lisp/mail/uudecode-resources/uuencoded.txt b/test/lisp/mail/uudecode-resources/uuencoded.txt new file mode 100644 index 00000000000..1d2f888bea3 --- /dev/null +++ b/test/lisp/mail/uudecode-resources/uuencoded.txt @@ -0,0 +1,19 @@ +begin 644 uudecoded.txt +M5&AI<R!I<R!A('1E<W0@9FEL92!E;F-O9&5D('=I=&@@=75E;F-O9&4N"@I4 +M:&ES(&9I;&4@:7,@<&%R="!O9B!'3E4@16UA8W,N"@I'3E4@16UA8W,@:7,@ +M9G)E92!S;V9T=V%R93H@>6]U(&-A;B!R961I<W1R:6)U=&4@:70@86YD+V]R +M(&UO9&EF>0II="!U;F1E<B!T:&4@=&5R;7,@;V8@=&AE($=.52!'96YE<F%L +M(%!U8FQI8R!,:6-E;G-E(&%S('!U8FQI<VAE9"!B>0IT:&4@1G)E92!3;V9T +M=V%R92!&;W5N9&%T:6]N+"!E:71H97(@=F5R<VEO;B`S(&]F('1H92!,:6-E +M;G-E+"!O<@HH870@>6]U<B!O<'1I;VXI(&%N>2!L871E<B!V97)S:6]N+@H* +M1TY5($5M86-S(&ES(&1I<W1R:6)U=&5D(&EN('1H92!H;W!E('1H870@:70@ +M=VEL;"!B92!U<V5F=6PL"F)U="!7251(3U54($%.62!705)204Y463L@=VET +M:&]U="!E=F5N('1H92!I;7!L:65D('=A<G)A;G1Y(&]F"DU%4D-(04Y404)) +M3$E462!O<B!&251.15-3($9/4B!!(%!!4E1)0U5,05(@4%524$]312X@(%-E +M92!T:&4*1TY5($=E;F5R86P@4'5B;&EC($QI8V5N<V4@9F]R(&UO<F4@9&5T +M86EL<RX*"EEO=2!S:&]U;&0@:&%V92!R96-E:79E9"!A(&-O<'D@;V8@=&AE +M($=.52!'96YE<F%L(%!U8FQI8R!,:6-E;G-E"F%L;VYG('=I=&@@1TY5($5M +M86-S+B`@268@;F]T+"!S964@/&AT='!S.B\O=W=W+F=N=2YO<F<O;&EC96YS +&97,O/BX* +` +end diff --git a/test/lisp/mail/uudecode-tests.el b/test/lisp/mail/uudecode-tests.el new file mode 100644 index 00000000000..7946e99dbc9 --- /dev/null +++ b/test/lisp/mail/uudecode-tests.el @@ -0,0 +1,75 @@ +;;; uudecode-tests.el --- Tests for uudecode.el -*- lexical-binding: t -*- + +;; Copyright (C) 2019-2022 Free Software Foundation, Inc. + +;; Author: Stefan Kangas <stefankangas@gmail.com> + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;;; Code: + +(require 'ert) +(require 'ert-x) +(require 'uudecode) + +(defun uudecode-tests-read-file (file) + "Read contents of FILE and return as string." + (with-temp-buffer + (insert-file-contents file) + (buffer-string))) + +(defvar uudecode-tests-encoded-str + (uudecode-tests-read-file (ert-resource-file "uuencoded.txt")) + "Uuencoded data for bookmark-tests.el. +Same as `uudecode-tests-decoded-str' but uuencoded.") +(defvar uudecode-tests-decoded-str + (uudecode-tests-read-file (ert-resource-file "uudecoded.txt")) + "Plain text data for bookmark-tests.el. +Same as `uudecode-tests-encoded-str' but plain text.") + +(ert-deftest uudecode-tests-decode-region-internal () + ;; Write to buffer + (with-temp-buffer + (insert uudecode-tests-encoded-str) + (uudecode-decode-region-internal (point-min) (point-max)) + (should (equal (buffer-string) uudecode-tests-decoded-str))) + ;; Write to file + (with-temp-buffer + (ert-with-temp-file tmpfile + (insert uudecode-tests-encoded-str) + (uudecode-decode-region-internal (point-min) (point-max) tmpfile) + (should (equal (uudecode-tests-read-file tmpfile) + uudecode-tests-decoded-str))))) + +(ert-deftest uudecode-tests-decode-region-external () + ;; Write to buffer + (when uudecode-use-external + (with-temp-buffer + (insert uudecode-tests-encoded-str) + (uudecode-decode-region-external (point-min) (point-max)) + (should (equal (buffer-string) uudecode-tests-decoded-str))) + ;; Write to file + (with-temp-buffer + (ert-with-temp-file tmpfile + (insert uudecode-tests-encoded-str) + (uudecode-decode-region-external (point-min) (point-max) tmpfile) + (should (equal (uudecode-tests-read-file tmpfile) + uudecode-tests-decoded-str)))))) + +(provide 'uudecode-tests) +;;; uudecode-tests.el ends here |