summaryrefslogtreecommitdiff
path: root/test/lisp/calendar
diff options
context:
space:
mode:
Diffstat (limited to 'test/lisp/calendar')
-rw-r--r--test/lisp/calendar/cal-french-tests.el114
-rw-r--r--test/lisp/calendar/cal-julian-tests.el72
-rw-r--r--test/lisp/calendar/icalendar-resources/import-bug-11473.diary-european10
-rw-r--r--test/lisp/calendar/icalendar-resources/import-bug-11473.ics54
-rw-r--r--test/lisp/calendar/icalendar-resources/import-bug-22092.diary-american6
-rw-r--r--test/lisp/calendar/icalendar-resources/import-bug-22092.diary-european6
-rw-r--r--test/lisp/calendar/icalendar-resources/import-bug-22092.diary-iso6
-rw-r--r--test/lisp/calendar/icalendar-resources/import-bug-22092.ics30
-rw-r--r--test/lisp/calendar/icalendar-resources/import-bug-24199.diary-american5
-rw-r--r--test/lisp/calendar/icalendar-resources/import-bug-24199.diary-european5
-rw-r--r--test/lisp/calendar/icalendar-resources/import-bug-24199.diary-iso5
-rw-r--r--test/lisp/calendar/icalendar-resources/import-bug-24199.ics25
-rw-r--r--test/lisp/calendar/icalendar-resources/import-bug-33277.diary-american1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-bug-33277.diary-european1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-bug-33277.diary-iso1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-bug-33277.ics15
-rw-r--r--test/lisp/calendar/icalendar-resources/import-bug-6766.diary-american7
-rw-r--r--test/lisp/calendar/icalendar-resources/import-bug-6766.diary-european7
-rw-r--r--test/lisp/calendar/icalendar-resources/import-bug-6766.diary-iso7
-rw-r--r--test/lisp/calendar/icalendar-resources/import-bug-6766.ics28
-rw-r--r--test/lisp/calendar/icalendar-resources/import-duration-2.diary-american3
-rw-r--r--test/lisp/calendar/icalendar-resources/import-duration-2.diary-european3
-rw-r--r--test/lisp/calendar/icalendar-resources/import-duration-2.diary-iso3
-rw-r--r--test/lisp/calendar/icalendar-resources/import-duration-2.ics17
-rw-r--r--test/lisp/calendar/icalendar-resources/import-duration.diary-american1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-duration.diary-european1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-duration.diary-iso1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-duration.ics10
-rw-r--r--test/lisp/calendar/icalendar-resources/import-multiple-vcalendars.diary-american4
-rw-r--r--test/lisp/calendar/icalendar-resources/import-multiple-vcalendars.diary-european4
-rw-r--r--test/lisp/calendar/icalendar-resources/import-multiple-vcalendars.diary-iso4
-rw-r--r--test/lisp/calendar/icalendar-resources/import-multiple-vcalendars.ics21
-rw-r--r--test/lisp/calendar/icalendar-resources/import-non-recurring-1.diary-american1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-non-recurring-1.diary-european1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-non-recurring-1.diary-iso1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-non-recurring-1.ics10
-rw-r--r--test/lisp/calendar/icalendar-resources/import-non-recurring-all-day.diary-american1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-non-recurring-all-day.diary-european1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-non-recurring-all-day.diary-iso1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-non-recurring-all-day.ics9
-rw-r--r--test/lisp/calendar/icalendar-resources/import-non-recurring-another-example.diary-american4
-rw-r--r--test/lisp/calendar/icalendar-resources/import-non-recurring-another-example.diary-european4
-rw-r--r--test/lisp/calendar/icalendar-resources/import-non-recurring-another-example.diary-iso4
-rw-r--r--test/lisp/calendar/icalendar-resources/import-non-recurring-another-example.ics23
-rw-r--r--test/lisp/calendar/icalendar-resources/import-non-recurring-block.diary-american4
-rw-r--r--test/lisp/calendar/icalendar-resources/import-non-recurring-block.diary-european4
-rw-r--r--test/lisp/calendar/icalendar-resources/import-non-recurring-block.diary-iso4
-rw-r--r--test/lisp/calendar/icalendar-resources/import-non-recurring-block.ics16
-rw-r--r--test/lisp/calendar/icalendar-resources/import-non-recurring-folded-summary.diary-american4
-rw-r--r--test/lisp/calendar/icalendar-resources/import-non-recurring-folded-summary.diary-european4
-rw-r--r--test/lisp/calendar/icalendar-resources/import-non-recurring-folded-summary.diary-iso4
-rw-r--r--test/lisp/calendar/icalendar-resources/import-non-recurring-folded-summary.ics25
-rw-r--r--test/lisp/calendar/icalendar-resources/import-non-recurring-long-summary.diary-american1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-non-recurring-long-summary.diary-european1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-non-recurring-long-summary.diary-iso1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-non-recurring-long-summary.ics10
-rw-r--r--test/lisp/calendar/icalendar-resources/import-real-world-2003-05-29.diary-american6
-rw-r--r--test/lisp/calendar/icalendar-resources/import-real-world-2003-05-29.diary-european6
-rw-r--r--test/lisp/calendar/icalendar-resources/import-real-world-2003-05-29.ics54
-rw-r--r--test/lisp/calendar/icalendar-resources/import-real-world-2003-06-18a.diary-american6
-rw-r--r--test/lisp/calendar/icalendar-resources/import-real-world-2003-06-18a.diary-european6
-rw-r--r--test/lisp/calendar/icalendar-resources/import-real-world-2003-06-18a.ics36
-rw-r--r--test/lisp/calendar/icalendar-resources/import-real-world-2003-06-18b.diary-american6
-rw-r--r--test/lisp/calendar/icalendar-resources/import-real-world-2003-06-18b.diary-european6
-rw-r--r--test/lisp/calendar/icalendar-resources/import-real-world-2003-06-18b.ics55
-rw-r--r--test/lisp/calendar/icalendar-resources/import-real-world-2004-11-19.diary-american19
-rw-r--r--test/lisp/calendar/icalendar-resources/import-real-world-2004-11-19.diary-european19
-rw-r--r--test/lisp/calendar/icalendar-resources/import-real-world-2004-11-19.ics120
-rw-r--r--test/lisp/calendar/icalendar-resources/import-real-world-2005-02-07.diary-american5
-rw-r--r--test/lisp/calendar/icalendar-resources/import-real-world-2005-02-07.diary-european5
-rw-r--r--test/lisp/calendar/icalendar-resources/import-real-world-2005-02-07.ics26
-rw-r--r--test/lisp/calendar/icalendar-resources/import-real-world-2005-03-01.diary-american2
-rw-r--r--test/lisp/calendar/icalendar-resources/import-real-world-2005-03-01.diary-european2
-rw-r--r--test/lisp/calendar/icalendar-resources/import-real-world-2005-03-01.ics11
-rw-r--r--test/lisp/calendar/icalendar-resources/import-real-world-no-dst.diary-american4
-rw-r--r--test/lisp/calendar/icalendar-resources/import-real-world-no-dst.diary-european4
-rw-r--r--test/lisp/calendar/icalendar-resources/import-real-world-no-dst.ics26
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-american1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-european1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-iso1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-anniversary.ics11
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-bi-weekly.diary-american1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-bi-weekly.diary-european1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-bi-weekly.diary-iso1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-bi-weekly.ics11
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-daily-long.diary-american1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-daily-long.diary-european1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-daily-long.diary-iso1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-daily-long.ics11
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-daily-short.diary-american1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-daily-short.diary-european1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-daily-short.diary-iso1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-daily-short.ics11
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-month.diary-american1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-month.diary-european1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-month.diary-iso1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-month.ics11
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-year.diary-american1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-year.diary-european1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-year.diary-iso1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-year.ics10
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-monthly.diary-american1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-monthly.diary-european1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-monthly.diary-iso1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-monthly.ics11
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-yearly.diary-american1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-yearly.diary-european1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-yearly.diary-iso1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-count-yearly.ics11
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-daily-two-day.diary-american1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-daily-two-day.diary-european1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-daily-two-day.diary-iso1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-daily-two-day.ics10
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-daily-with-exceptions.diary-american1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-daily-with-exceptions.diary-european1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-daily-with-exceptions.diary-iso1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-daily-with-exceptions.ics12
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-daily.diary-american1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-daily.diary-european1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-daily.diary-iso1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-daily.ics11
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-monthly-no-end.diary-american1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-monthly-no-end.diary-european1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-monthly-no-end.diary-iso1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-monthly-no-end.ics11
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-monthly-with-end.diary-american1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-monthly-with-end.diary-european1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-monthly-with-end.diary-iso1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-monthly-with-end.ics11
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-weekly.diary-american1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-weekly.diary-european1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-weekly.diary-iso1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-weekly.ics11
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-american1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-european1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-iso1
-rw-r--r--test/lisp/calendar/icalendar-resources/import-rrule-yearly.ics11
-rw-r--r--test/lisp/calendar/icalendar-resources/import-with-timezone.diary-iso2
-rw-r--r--test/lisp/calendar/icalendar-resources/import-with-timezone.ics27
-rw-r--r--test/lisp/calendar/icalendar-resources/import-with-uid.diary-american2
-rw-r--r--test/lisp/calendar/icalendar-resources/import-with-uid.diary-european2
-rw-r--r--test/lisp/calendar/icalendar-resources/import-with-uid.diary-iso2
-rw-r--r--test/lisp/calendar/icalendar-resources/import-with-uid.ics10
-rw-r--r--test/lisp/calendar/icalendar-tests.el1606
-rw-r--r--test/lisp/calendar/iso8601-tests.el354
-rw-r--r--test/lisp/calendar/lunar-tests.el73
-rw-r--r--test/lisp/calendar/parse-time-tests.el66
-rw-r--r--test/lisp/calendar/solar-tests.el48
-rw-r--r--test/lisp/calendar/time-date-tests.el216
-rw-r--r--test/lisp/calendar/todo-mode-resources/todo-test-1.todo10
-rw-r--r--test/lisp/calendar/todo-mode-tests.el436
151 files changed, 2895 insertions, 1207 deletions
diff --git a/test/lisp/calendar/cal-french-tests.el b/test/lisp/calendar/cal-french-tests.el
new file mode 100644
index 00000000000..771681228e6
--- /dev/null
+++ b/test/lisp/calendar/cal-french-tests.el
@@ -0,0 +1,114 @@
+;;; cal-french-tests.el --- tests for cal-french.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/>.
+
+;;; Code:
+
+(require 'ert)
+(require 'cal-french)
+
+(defconst cal-french-test-cases
+ '(
+ (1792 9 22 "Primidi 1 Vendémiaire an 1 de la Révolution, jour du Raisin")
+ (1793 10 23 "Duodi 2 Brumaire an 2 de la Révolution, jour du Céleri")
+ (1794 7 27 "Nonidi 9 Thermidor an 2 de la Révolution, jour de la Mûre")
+ (1794 11 23 "Tridi 3 Frimaire an 3 de la Révolution, jour de la Chicorée")
+ (1795 10 5 "Tridi 13 Vendémiaire an 4 de la Révolution, jour du Potiron")
+ (1795 12 25 "Quartidi 4 Nivôse an 4 de la Révolution, jour du Soufre")
+ (1797 1 24 "Quintidi 5 Pluviôse an 5 de la Révolution, jour du Taureau")
+ (1798 2 24 "Sextidi 6 Ventôse an 6 de la Révolution, jour de l'Asaret")
+ (1799 11 9 "Octidi 18 Brumaire an 8 de la Révolution, jour de la Dentelaire")
+ (1801 3 29 "Octidi 8 Germinal an 9 de la Révolution, jour de la Jonquille")
+ (1804 4 30 "Décadi 10 Floréal an 12 de la Révolution, jour du Rateau")
+ (1807 6 1 "Duodi 12 Prairial an 15 de la Révolution, jour de la Bétoine")
+ (1810 7 3 "Quartidi 14 Messidor an 18 de la Révolution, jour de la Lavande")
+ (1813 8 4 "Sextidi 16 Thermidor an 21 de la Révolution, jour de la Guimauve")
+ (1816 9 4 "Octidi 18 Fructidor an 24 de la Révolution, jour du Nerprun")
+ (2000 1 1 "Duodi 12 Nivôse an 208 de la Révolution, jour de l'Argile")
+ (2021 7 11 "Tridi 23 Messidor an 229 de la Révolution, jour du Haricot")
+ (2001 5 11 "Duodi 22 Floréal an 209 de la Révolution, jour de la Fritillaire")
+ (1792 9 22 "Primidi 1 Vendémiaire an 1 de la Révolution, jour du Raisin")
+ (1793 9 21 "Quintidi 5 jour complémentaire an 1 de la Révolution, jour des Récompenses")
+ (1793 9 22 "Primidi 1 Vendémiaire an 2 de la Révolution, jour du Raisin")
+ (1794 9 21 "Quintidi 5 jour complémentaire an 2 de la Révolution, jour des Récompenses")
+ (1794 9 22 "Primidi 1 Vendémiaire an 3 de la Révolution, jour du Raisin")
+ (1795 9 22 "Sextidi 6 jour complémentaire an 3 de la Révolution, jour de la Révolution")
+ (1795 9 23 "Primidi 1 Vendémiaire an 4 de la Révolution, jour du Raisin")
+ (1796 9 21 "Quintidi 5 jour complémentaire an 4 de la Révolution, jour des Récompenses")
+ (1796 9 22 "Primidi 1 Vendémiaire an 5 de la Révolution, jour du Raisin")
+ (1797 9 21 "Quintidi 5 jour complémentaire an 5 de la Révolution, jour des Récompenses")
+ (1797 9 22 "Primidi 1 Vendémiaire an 6 de la Révolution, jour du Raisin")
+ (1799 9 22 "Sextidi 6 jour complémentaire an 7 de la Révolution, jour de la Révolution")
+ (1799 9 23 "Primidi 1 Vendémiaire an 8 de la Révolution, jour du Raisin")
+ (1800 9 22 "Quintidi 5 jour complémentaire an 8 de la Révolution, jour des Récompenses")
+ (1800 9 23 "Primidi 1 Vendémiaire an 9 de la Révolution, jour du Raisin")
+ (1801 9 22 "Quintidi 5 jour complémentaire an 9 de la Révolution, jour des Récompenses")
+ (1801 9 23 "Primidi 1 Vendémiaire an 10 de la Révolution, jour du Raisin")
+ (1823 9 22 "Quintidi 5 jour complémentaire an 31 de la Révolution, jour des Récompenses")
+ (1823 9 23 "Primidi 1 Vendémiaire an 32 de la Révolution, jour du Raisin")
+ (1824 9 22 "Sextidi 6 jour complémentaire an 32 de la Révolution, jour de la Révolution")
+ (1824 9 23 "Primidi 1 Vendémiaire an 33 de la Révolution, jour du Raisin")
+ (1825 9 22 "Quintidi 5 jour complémentaire an 33 de la Révolution, jour des Récompenses")
+ (1825 9 23 "Primidi 1 Vendémiaire an 34 de la Révolution, jour du Raisin")
+ (1892 9 21 "Quintidi 5 jour complémentaire an 100 de la Révolution, jour des Récompenses")
+ (1892 9 22 "Primidi 1 Vendémiaire an 101 de la Révolution, jour du Raisin")
+ (1900 9 22 "Sextidi 6 jour complémentaire an 108 de la Révolution, jour de la Révolution")
+ (1900 9 23 "Primidi 1 Vendémiaire an 109 de la Révolution, jour du Raisin")
+ (1992 9 21 "Quintidi 5 jour complémentaire an 200 de la Révolution, jour des Récompenses")
+ (1992 9 22 "Primidi 1 Vendémiaire an 201 de la Révolution, jour du Raisin")
+ (2000 9 21 "Sextidi 6 jour complémentaire an 208 de la Révolution, jour de la Révolution")
+ (2000 9 22 "Primidi 1 Vendémiaire an 209 de la Révolution, jour du Raisin")
+ (2092 9 20 "Quintidi 5 jour complémentaire an 300 de la Révolution, jour des Récompenses")
+ (2092 9 21 "Primidi 1 Vendémiaire an 301 de la Révolution, jour du Raisin")
+ (2100 9 21 "Sextidi 6 jour complémentaire an 308 de la Révolution, jour de la Révolution")
+ (2100 9 22 "Primidi 1 Vendémiaire an 309 de la Révolution, jour du Raisin")
+ (2192 9 21 "Sextidi 6 jour complémentaire an 400 de la Révolution, jour de la Révolution")
+ (2192 9 22 "Primidi 1 Vendémiaire an 401 de la Révolution, jour du Raisin")
+ (2193 9 21 "Quintidi 5 jour complémentaire an 401 de la Révolution, jour des Récompenses")
+ (2199 9 22 "Primidi 1 Vendémiaire an 408 de la Révolution, jour du Raisin")
+ (2200 9 22 "Sextidi 6 jour complémentaire an 408 de la Révolution, jour de la Révolution")
+ (2791 9 23 "Primidi 1 Vendémiaire an 1000 de la Révolution, jour du Raisin")
+ (2792 9 22 "Primidi 1 Vendémiaire an 1001 de la Révolution, jour du Raisin")
+ (3000 1 1 "Duodi 12 Nivôse an 1208 de la Révolution, jour de l'Argile")
+ (3001 1 1 "Primidi 11 Nivôse an 1209 de la Révolution, jour du Granit")
+ (3791 9 22 "Primidi 1 Vendémiaire an 2000 de la Révolution, jour du Raisin")
+ (3792 9 22 "Primidi 1 Vendémiaire an 2001 de la Révolution, jour du Raisin")
+ (4000 1 1 "Duodi 12 Nivôse an 2208 de la Révolution, jour de l'Argile")
+ (4001 1 1 "Duodi 12 Nivôse an 2209 de la Révolution, jour de l'Argile")
+ (4320 9 10 "Quartidi 24 Fructidor an 2528 de la Révolution, jour du Sorgho")
+ (4320 9 11 "Quintidi 25 Fructidor an 2528 de la Révolution, jour de l'Écrevisse")
+ (4791 9 23 "Primidi 1 Vendémiaire an 3000 de la Révolution, jour du Raisin")
+ (4792 9 22 "Primidi 1 Vendémiaire an 3001 de la Révolution, jour du Raisin")
+ (5000 1 1 "Duodi 12 Nivôse an 3208 de la Révolution, jour de l'Argile")
+ (5001 1 1 "Primidi 11 Nivôse an 3209 de la Révolution, jour du Granit")
+ (5791 9 22 "Primidi 1 Vendémiaire an 4000 de la Révolution, jour du Raisin")
+ (5792 9 21 "Primidi 1 Vendémiaire an 4001 de la Révolution, jour du Raisin")
+ (6000 1 1 "Tridi 13 Nivôse an 4208 de la Révolution, jour de l'Ardoise")
+ (6001 1 1 "Tridi 13 Nivôse an 4209 de la Révolution, jour de l'Ardoise")
+ (6791 9 22 "Primidi 1 Vendémiaire an 5000 de la Révolution, jour du Raisin")
+ (6792 9 21 "Primidi 1 Vendémiaire an 5001 de la Révolution, jour du Raisin")
+ (7791 9 21 "Primidi 1 Vendémiaire an 6000 de la Révolution, jour du Raisin")
+ (7792 9 21 "Primidi 1 Vendémiaire an 6001 de la Révolution, jour du Raisin")
+ ))
+
+(ert-deftest cal-french-tests ()
+ (pcase-dolist (`(,y ,m ,d ,str) cal-french-test-cases)
+ (should (equal (calendar-french-date-string (list m d y)) str))))
+
+(provide 'cal-french-tests)
+;;; cal-french-tests.el ends here
diff --git a/test/lisp/calendar/cal-julian-tests.el b/test/lisp/calendar/cal-julian-tests.el
new file mode 100644
index 00000000000..46d49c68c1e
--- /dev/null
+++ b/test/lisp/calendar/cal-julian-tests.el
@@ -0,0 +1,72 @@
+;;; cal-julian-tests.el --- tests for calendar/cal-julian.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/>.
+
+;;; Code:
+
+(require 'ert)
+(require 'cal-julian)
+
+(ert-deftest cal-julian-test-to-absolute ()
+ (should (equal (calendar-gregorian-from-absolute
+ (calendar-julian-to-absolute
+ '(10 25 1917)))
+ '(11 7 1917))))
+
+(ert-deftest cal-julian-test-from-absolute ()
+ (should (equal (calendar-julian-from-absolute
+ (calendar-absolute-from-gregorian
+ '(11 7 1917)))
+ '(10 25 1917))))
+
+(ert-deftest cal-julian-test-date-string ()
+ (should (equal (let ((calendar-date-display-form calendar-iso-date-display-form))
+ (calendar-julian-date-string '(11 7 1917)))
+ "1917-10-25")))
+
+(defmacro with-cal-julian-test (&rest body)
+ `(save-window-excursion
+ (unwind-protect
+ (progn
+ (calendar)
+ ,@body)
+ (kill-buffer "*Calendar*"))))
+
+(ert-deftest cal-julian-test-goto-date ()
+ (with-cal-julian-test
+ (calendar-julian-goto-date '(10 25 1917))
+ (should (looking-at "7"))))
+
+(ert-deftest cal-julian-test-astro-to-and-from-absolute ()
+ (should (= (+ (calendar-astro-to-absolute 0.0)
+ (calendar-astro-from-absolute 0.0))
+ 0.0)))
+
+(ert-deftest cal-julian-calendar-astro-date-string ()
+ (should (equal (calendar-astro-date-string '(10 25 1917)) "2421527")))
+
+(ert-deftest calendar-astro-goto-day-number ()
+ (with-cal-julian-test
+ (calendar-astro-goto-day-number 2421527)
+ (backward-char)
+ (should (looking-at "25"))))
+
+(provide 'cal-julian-tests)
+;;; cal-julian-tests.el ends here
diff --git a/test/lisp/calendar/icalendar-resources/import-bug-11473.diary-european b/test/lisp/calendar/icalendar-resources/import-bug-11473.diary-european
new file mode 100644
index 00000000000..97348ae0498
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-bug-11473.diary-european
@@ -0,0 +1,10 @@
+&15/5/2012 15:00-15:30 Query
+ Desc:
+ Whassup?
+
+
+ Location: phone
+ Organizer: MAILTO:a.luser@foo.com
+ Status: CONFIRMED
+ Class: PUBLIC
+ UID: 040000008200E00074C5B7101A82E0080000000020FFAED0CFEFCC01000000000000000010000000575268034ECDB649A15349B1BF240F15
diff --git a/test/lisp/calendar/icalendar-resources/import-bug-11473.ics b/test/lisp/calendar/icalendar-resources/import-bug-11473.ics
new file mode 100644
index 00000000000..bc3a6c69fb7
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-bug-11473.ics
@@ -0,0 +1,54 @@
+BEGIN:VCALENDAR
+METHOD:REQUEST
+PRODID:Microsoft Exchange Server 2007
+VERSION:2.0
+BEGIN:VTIMEZONE
+TZID:(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna
+BEGIN:STANDARD
+DTSTART:16010101T030000
+TZOFFSETFROM:+0200
+TZOFFSETTO:+0100
+RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:16010101T020000
+TZOFFSETFROM:+0100
+TZOFFSETTO:+0200
+RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3
+END:DAYLIGHT
+END:VTIMEZONE
+BEGIN:VEVENT
+ORGANIZER;CN="A. Luser":MAILTO:a.luser@foo.com
+ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN="Luser, Oth
+ er":MAILTO:other.luser@foo.com
+DESCRIPTION;LANGUAGE=en-US:\nWhassup?\n\n
+SUMMARY;LANGUAGE=en-US:Query
+DTSTART;TZID="(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna"
+ :20120515T150000
+DTEND;TZID="(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna":2
+ 0120515T153000
+UID:040000008200E00074C5B7101A82E0080000000020FFAED0CFEFCC01000000000000000
+ 010000000575268034ECDB649A15349B1BF240F15
+RECURRENCE-ID;TZID="(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, V
+ ienna":20120515T170000
+CLASS:PUBLIC
+PRIORITY:5
+DTSTAMP:20120514T153645Z
+TRANSP:OPAQUE
+STATUS:CONFIRMED
+SEQUENCE:15
+LOCATION;LANGUAGE=en-US:phone
+X-MICROSOFT-CDO-APPT-SEQUENCE:15
+X-MICROSOFT-CDO-OWNERAPPTID:1907632092
+X-MICROSOFT-CDO-BUSYSTATUS:TENTATIVE
+X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY
+X-MICROSOFT-CDO-ALLDAYEVENT:FALSE
+X-MICROSOFT-CDO-IMPORTANCE:1
+X-MICROSOFT-CDO-INSTTYPE:3
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:REMINDER
+TRIGGER;RELATED=START:-PT15M
+END:VALARM
+END:VEVENT
+END:VCALENDAR \ No newline at end of file
diff --git a/test/lisp/calendar/icalendar-resources/import-bug-22092.diary-american b/test/lisp/calendar/icalendar-resources/import-bug-22092.diary-american
new file mode 100644
index 00000000000..392345fe0a2
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-bug-22092.diary-american
@@ -0,0 +1,6 @@
+&12/8/2014 18:30-22:55 Norwegian til Tromsoe-Langnes -
+ Desc: Fly med Norwegian, reservasjon. Fra Stavanger til Troms&#248; 8. des 2014 18:30, DY545Fly med Norwegian, reservasjon . Fra Stavanger til Troms&#248; 8. des 2014 21:00, DY390
+ Location: Stavanger-Sola
+ Organizer: noreply@norwegian.no
+ Class: PUBLIC
+ UID: RFCALITEM1
diff --git a/test/lisp/calendar/icalendar-resources/import-bug-22092.diary-european b/test/lisp/calendar/icalendar-resources/import-bug-22092.diary-european
new file mode 100644
index 00000000000..6a64cf6a8e9
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-bug-22092.diary-european
@@ -0,0 +1,6 @@
+&8/12/2014 18:30-22:55 Norwegian til Tromsoe-Langnes -
+ Desc: Fly med Norwegian, reservasjon. Fra Stavanger til Troms&#248; 8. des 2014 18:30, DY545Fly med Norwegian, reservasjon . Fra Stavanger til Troms&#248; 8. des 2014 21:00, DY390
+ Location: Stavanger-Sola
+ Organizer: noreply@norwegian.no
+ Class: PUBLIC
+ UID: RFCALITEM1
diff --git a/test/lisp/calendar/icalendar-resources/import-bug-22092.diary-iso b/test/lisp/calendar/icalendar-resources/import-bug-22092.diary-iso
new file mode 100644
index 00000000000..e0fadbf94dc
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-bug-22092.diary-iso
@@ -0,0 +1,6 @@
+&2014/12/8 18:30-22:55 Norwegian til Tromsoe-Langnes -
+ Desc: Fly med Norwegian, reservasjon. Fra Stavanger til Troms&#248; 8. des 2014 18:30, DY545Fly med Norwegian, reservasjon . Fra Stavanger til Troms&#248; 8. des 2014 21:00, DY390
+ Location: Stavanger-Sola
+ Organizer: noreply@norwegian.no
+ Class: PUBLIC
+ UID: RFCALITEM1
diff --git a/test/lisp/calendar/icalendar-resources/import-bug-22092.ics b/test/lisp/calendar/icalendar-resources/import-bug-22092.ics
new file mode 100644
index 00000000000..4a4c679da9c
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-bug-22092.ics
@@ -0,0 +1,30 @@
+BEGIN:VCALENDAR
+PRODID:-//www.norwegian.no//iCalendar MIMEDIR//EN
+VERSION:2.0
+METHOD:REQUEST
+BEGIN:VEVENT
+UID:RFCALITEM1
+SEQUENCE:1512040950
+DTSTAMP:20141204T095043Z
+ORGANIZER:noreply@norwegian.no
+DTSTART:20141208T173000Z
+
+DTEND:20141208T215500Z
+
+LOCATION:Stavanger-Sola
+
+DESCRIPTION:Fly med Norwegian, reservasjon. Fra Stavanger til Troms&#248; 8. des 2014 18:30, DY545Fly med Norwegian, reservasjon . Fra Stavanger til Troms&#248; 8. des 2014 21:00, DY390
+
+X-ALT-DESC;FMTTYPE=text/html:<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"><html><head><META NAME="Generator" CONTENT="MS Exchange Server version 08.00.0681.000"><title></title></head><body><b><font face="Calibri" size="3">Reisereferanse</p></body></html>
+SUMMARY:Norwegian til Tromsoe-Langnes -
+
+CATEGORIES:Appointment
+
+
+PRIORITY:5
+
+CLASS:PUBLIC
+
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
diff --git a/test/lisp/calendar/icalendar-resources/import-bug-24199.diary-american b/test/lisp/calendar/icalendar-resources/import-bug-24199.diary-american
new file mode 100644
index 00000000000..b3308f1fcfa
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-bug-24199.diary-american
@@ -0,0 +1,5 @@
+&%%(and (not (diary-date 1 6 2016)) (not (diary-date 2 3 2016)) (not (diary-date 3 2 2016)) (not (diary-date 5 4 2016)) (not (diary-date 6 1 2016)) (diary-float t 3 1) (diary-block 12 2 2015 1 1 9999)) 12:46-16:00 Summary
+ Desc: Desc
+ Location: Loc
+ Class: DEFAULT
+ UID: 9188710a-08a7-4061-bae3-d4cf4972599a
diff --git a/test/lisp/calendar/icalendar-resources/import-bug-24199.diary-european b/test/lisp/calendar/icalendar-resources/import-bug-24199.diary-european
new file mode 100644
index 00000000000..acba714b527
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-bug-24199.diary-european
@@ -0,0 +1,5 @@
+&%%(and (not (diary-date 6 1 2016)) (not (diary-date 3 2 2016)) (not (diary-date 2 3 2016)) (not (diary-date 4 5 2016)) (not (diary-date 1 6 2016)) (diary-float t 3 1) (diary-block 2 12 2015 1 1 9999)) 12:46-16:00 Summary
+ Desc: Desc
+ Location: Loc
+ Class: DEFAULT
+ UID: 9188710a-08a7-4061-bae3-d4cf4972599a
diff --git a/test/lisp/calendar/icalendar-resources/import-bug-24199.diary-iso b/test/lisp/calendar/icalendar-resources/import-bug-24199.diary-iso
new file mode 100644
index 00000000000..2c18395dea8
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-bug-24199.diary-iso
@@ -0,0 +1,5 @@
+&%%(and (not (diary-date 2016 1 6)) (not (diary-date 2016 2 3)) (not (diary-date 2016 3 2)) (not (diary-date 2016 5 4)) (not (diary-date 2016 6 1)) (diary-float t 3 1) (diary-block 2015 12 2 9999 1 1)) 12:46-16:00 Summary
+ Desc: Desc
+ Location: Loc
+ Class: DEFAULT
+ UID: 9188710a-08a7-4061-bae3-d4cf4972599a
diff --git a/test/lisp/calendar/icalendar-resources/import-bug-24199.ics b/test/lisp/calendar/icalendar-resources/import-bug-24199.ics
new file mode 100644
index 00000000000..a307c2da3ca
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-bug-24199.ics
@@ -0,0 +1,25 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+SUMMARY:Summary
+DESCRIPTION:Desc
+LOCATION:Loc
+DTSTART:20151202T124600
+DTEND:20151202T160000
+RRULE:FREQ=MONTHLY;BYDAY=1WE;INTERVAL=1
+EXDATE:20160106T114600Z
+EXDATE:20160203T114600Z
+EXDATE:20160302T114600Z
+EXDATE:20160504T104600Z
+EXDATE:20160601T104600Z
+CLASS:DEFAULT
+TRANSP:OPAQUE
+BEGIN:VALARM
+ACTION:DISPLAY
+TRIGGER;VALUE=DURATION:-PT3H
+END:VALARM
+LAST-MODIFIED:20160805T191040Z
+UID:9188710a-08a7-4061-bae3-d4cf4972599a
+END:VEVENT
+END:VCALENDAR
diff --git a/test/lisp/calendar/icalendar-resources/import-bug-33277.diary-american b/test/lisp/calendar/icalendar-resources/import-bug-33277.diary-american
new file mode 100644
index 00000000000..c546fa9a97c
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-bug-33277.diary-american
@@ -0,0 +1 @@
+&11/5/2018 21:00 event with same start/end time
diff --git a/test/lisp/calendar/icalendar-resources/import-bug-33277.diary-european b/test/lisp/calendar/icalendar-resources/import-bug-33277.diary-european
new file mode 100644
index 00000000000..28e53960536
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-bug-33277.diary-european
@@ -0,0 +1 @@
+&5/11/2018 21:00 event with same start/end time
diff --git a/test/lisp/calendar/icalendar-resources/import-bug-33277.diary-iso b/test/lisp/calendar/icalendar-resources/import-bug-33277.diary-iso
new file mode 100644
index 00000000000..faa7aeafeb5
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-bug-33277.diary-iso
@@ -0,0 +1 @@
+&2018/11/5 21:00 event with same start/end time
diff --git a/test/lisp/calendar/icalendar-resources/import-bug-33277.ics b/test/lisp/calendar/icalendar-resources/import-bug-33277.ics
new file mode 100644
index 00000000000..a4122a28007
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-bug-33277.ics
@@ -0,0 +1,15 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+DTSTART:20181105T200000Z
+DTSTAMP:20181105T181652Z
+DESCRIPTION:
+LAST-MODIFIED:20181105T181646Z
+LOCATION:
+SEQUENCE:0
+SUMMARY:event with same start/end time
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
+
diff --git a/test/lisp/calendar/icalendar-resources/import-bug-6766.diary-american b/test/lisp/calendar/icalendar-resources/import-bug-6766.diary-american
new file mode 100644
index 00000000000..30deea9911a
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-bug-6766.diary-american
@@ -0,0 +1,7 @@
+&%%(and (memq (calendar-day-of-week date) '(1 3 4 5)) (diary-cyclic 1 4 21 2010)) 11:30-12:00 Scrum
+ Status: CONFIRMED
+ Class: PUBLIC
+ UID: 8814e3f9-7482-408f-996c-3bfe486a1262
+&%%(and (memq (calendar-day-of-week date) '(2 4)) (diary-cyclic 1 4 22 2010)) Tues + Thurs thinking
+ Class: PUBLIC
+ UID: 8814e3f9-7482-408f-996c-3bfe486a1263
diff --git a/test/lisp/calendar/icalendar-resources/import-bug-6766.diary-european b/test/lisp/calendar/icalendar-resources/import-bug-6766.diary-european
new file mode 100644
index 00000000000..ba16c02305a
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-bug-6766.diary-european
@@ -0,0 +1,7 @@
+&%%(and (memq (calendar-day-of-week date) '(1 3 4 5)) (diary-cyclic 1 21 4 2010)) 11:30-12:00 Scrum
+ Status: CONFIRMED
+ Class: PUBLIC
+ UID: 8814e3f9-7482-408f-996c-3bfe486a1262
+&%%(and (memq (calendar-day-of-week date) '(2 4)) (diary-cyclic 1 22 4 2010)) Tues + Thurs thinking
+ Class: PUBLIC
+ UID: 8814e3f9-7482-408f-996c-3bfe486a1263
diff --git a/test/lisp/calendar/icalendar-resources/import-bug-6766.diary-iso b/test/lisp/calendar/icalendar-resources/import-bug-6766.diary-iso
new file mode 100644
index 00000000000..7794e586f37
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-bug-6766.diary-iso
@@ -0,0 +1,7 @@
+&%%(and (memq (calendar-day-of-week date) '(1 3 4 5)) (diary-cyclic 1 2010 4 21)) 11:30-12:00 Scrum
+ Status: CONFIRMED
+ Class: PUBLIC
+ UID: 8814e3f9-7482-408f-996c-3bfe486a1262
+&%%(and (memq (calendar-day-of-week date) '(2 4)) (diary-cyclic 1 2010 4 22)) Tues + Thurs thinking
+ Class: PUBLIC
+ UID: 8814e3f9-7482-408f-996c-3bfe486a1263
diff --git a/test/lisp/calendar/icalendar-resources/import-bug-6766.ics b/test/lisp/calendar/icalendar-resources/import-bug-6766.ics
new file mode 100644
index 00000000000..451391be025
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-bug-6766.ics
@@ -0,0 +1,28 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+CLASS:PUBLIC
+DTEND;TZID=America/New_York:20100421T120000
+DTSTAMP:20100525T141214Z
+DTSTART;TZID=America/New_York:20100421T113000
+RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,WE,TH,FR
+SEQUENCE:1
+STATUS:CONFIRMED
+SUMMARY:Scrum
+TRANSP:OPAQUE
+UID:8814e3f9-7482-408f-996c-3bfe486a1262
+END:VEVENT
+BEGIN:VEVENT
+CLASS:PUBLIC
+DTSTAMP:20100525T141214Z
+DTSTART;VALUE=DATE:20100422
+DTEND;VALUE=DATE:20100423
+RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=TU,TH
+SEQUENCE:1
+SUMMARY:Tues + Thurs thinking
+TRANSP:OPAQUE
+UID:8814e3f9-7482-408f-996c-3bfe486a1263
+END:VEVENT
+END:VCALENDAR
+
diff --git a/test/lisp/calendar/icalendar-resources/import-duration-2.diary-american b/test/lisp/calendar/icalendar-resources/import-duration-2.diary-american
new file mode 100644
index 00000000000..56f41d6ad9e
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-duration-2.diary-american
@@ -0,0 +1,3 @@
+&%%(and (diary-cyclic 1 12 21 2001) (diary-block 12 21 2001 12 29 2001)) Urlaub
+ Class: PUBLIC
+ UID: 20041127T183329Z-18215-1001-4536-49109@andromeda
diff --git a/test/lisp/calendar/icalendar-resources/import-duration-2.diary-european b/test/lisp/calendar/icalendar-resources/import-duration-2.diary-european
new file mode 100644
index 00000000000..999102ab6b4
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-duration-2.diary-european
@@ -0,0 +1,3 @@
+&%%(and (diary-cyclic 1 21 12 2001) (diary-block 21 12 2001 29 12 2001)) Urlaub
+ Class: PUBLIC
+ UID: 20041127T183329Z-18215-1001-4536-49109@andromeda
diff --git a/test/lisp/calendar/icalendar-resources/import-duration-2.diary-iso b/test/lisp/calendar/icalendar-resources/import-duration-2.diary-iso
new file mode 100644
index 00000000000..393937e6cd9
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-duration-2.diary-iso
@@ -0,0 +1,3 @@
+&%%(and (diary-cyclic 1 2001 12 21) (diary-block 2001 12 21 2001 12 29)) Urlaub
+ Class: PUBLIC
+ UID: 20041127T183329Z-18215-1001-4536-49109@andromeda
diff --git a/test/lisp/calendar/icalendar-resources/import-duration-2.ics b/test/lisp/calendar/icalendar-resources/import-duration-2.ics
new file mode 100644
index 00000000000..eb8a03ba36f
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-duration-2.ics
@@ -0,0 +1,17 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+UID:20041127T183329Z-18215-1001-4536-49109@andromeda
+DTSTAMP:20041127T183315Z
+LAST-MODIFIED:20041127T183329
+SUMMARY:Urlaub
+DTSTART;VALUE=DATE:20011221
+DTEND;VALUE=DATE:20011221
+RRULE:FREQ=DAILY;UNTIL=20011229;INTERVAL=1;WKST=SU
+CLASS:PUBLIC
+SEQUENCE:1
+CREATED:20041127T183329
+END:VEVENT
+END:VCALENDAR
+
diff --git a/test/lisp/calendar/icalendar-resources/import-duration.diary-american b/test/lisp/calendar/icalendar-resources/import-duration.diary-american
new file mode 100644
index 00000000000..268736a8cd0
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-duration.diary-american
@@ -0,0 +1 @@
+&%%(and (diary-block 2 17 2005 2 23 2005)) duration
diff --git a/test/lisp/calendar/icalendar-resources/import-duration.diary-european b/test/lisp/calendar/icalendar-resources/import-duration.diary-european
new file mode 100644
index 00000000000..7d852ddcd3c
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-duration.diary-european
@@ -0,0 +1 @@
+&%%(and (diary-block 17 2 2005 23 2 2005)) duration
diff --git a/test/lisp/calendar/icalendar-resources/import-duration.diary-iso b/test/lisp/calendar/icalendar-resources/import-duration.diary-iso
new file mode 100644
index 00000000000..5d3a714284e
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-duration.diary-iso
@@ -0,0 +1 @@
+&%%(and (diary-block 2005 2 17 2005 2 23)) duration
diff --git a/test/lisp/calendar/icalendar-resources/import-duration.ics b/test/lisp/calendar/icalendar-resources/import-duration.ics
new file mode 100644
index 00000000000..67f5c73571b
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-duration.ics
@@ -0,0 +1,10 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+DTSTART;VALUE=DATE:20050217
+SUMMARY:duration
+DURATION:P7D
+END:VEVENT
+END:VCALENDAR
+
diff --git a/test/lisp/calendar/icalendar-resources/import-multiple-vcalendars.diary-american b/test/lisp/calendar/icalendar-resources/import-multiple-vcalendars.diary-american
new file mode 100644
index 00000000000..d1b1992a022
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-multiple-vcalendars.diary-american
@@ -0,0 +1,4 @@
+&7/23/2011 event-1
+&7/24/2011 event-2
+&7/25/2011 event-3a
+&7/25/2011 event-3b
diff --git a/test/lisp/calendar/icalendar-resources/import-multiple-vcalendars.diary-european b/test/lisp/calendar/icalendar-resources/import-multiple-vcalendars.diary-european
new file mode 100644
index 00000000000..f068354220c
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-multiple-vcalendars.diary-european
@@ -0,0 +1,4 @@
+&23/7/2011 event-1
+&24/7/2011 event-2
+&25/7/2011 event-3a
+&25/7/2011 event-3b
diff --git a/test/lisp/calendar/icalendar-resources/import-multiple-vcalendars.diary-iso b/test/lisp/calendar/icalendar-resources/import-multiple-vcalendars.diary-iso
new file mode 100644
index 00000000000..5685e4708a7
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-multiple-vcalendars.diary-iso
@@ -0,0 +1,4 @@
+&2011/7/23 event-1
+&2011/7/24 event-2
+&2011/7/25 event-3a
+&2011/7/25 event-3b
diff --git a/test/lisp/calendar/icalendar-resources/import-multiple-vcalendars.ics b/test/lisp/calendar/icalendar-resources/import-multiple-vcalendars.ics
new file mode 100644
index 00000000000..69a02c09b1b
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-multiple-vcalendars.ics
@@ -0,0 +1,21 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+DTSTART;VALUE=DATE:20110723
+SUMMARY:event-1
+END:VEVENT
+BEGIN:VEVENT
+DTSTART;VALUE=DATE:20110724
+SUMMARY:event-2
+END:VEVENT
+BEGIN:VEVENT
+DTSTART;VALUE=DATE:20110725
+SUMMARY:event-3a
+END:VEVENT
+BEGIN:VEVENT
+DTSTART;VALUE=DATE:20110725
+SUMMARY:event-3b
+END:VEVENT
+END:VCALENDAR
+
diff --git a/test/lisp/calendar/icalendar-resources/import-non-recurring-1.diary-american b/test/lisp/calendar/icalendar-resources/import-non-recurring-1.diary-american
new file mode 100644
index 00000000000..780e3a8ce64
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-non-recurring-1.diary-american
@@ -0,0 +1 @@
+&9/19/2003 09:00-11:30 non-recurring
diff --git a/test/lisp/calendar/icalendar-resources/import-non-recurring-1.diary-european b/test/lisp/calendar/icalendar-resources/import-non-recurring-1.diary-european
new file mode 100644
index 00000000000..7e0cd21b784
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-non-recurring-1.diary-european
@@ -0,0 +1 @@
+&19/9/2003 09:00-11:30 non-recurring
diff --git a/test/lisp/calendar/icalendar-resources/import-non-recurring-1.diary-iso b/test/lisp/calendar/icalendar-resources/import-non-recurring-1.diary-iso
new file mode 100644
index 00000000000..c7311286619
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-non-recurring-1.diary-iso
@@ -0,0 +1 @@
+&2003/9/19 09:00-11:30 non-recurring
diff --git a/test/lisp/calendar/icalendar-resources/import-non-recurring-1.ics b/test/lisp/calendar/icalendar-resources/import-non-recurring-1.ics
new file mode 100644
index 00000000000..cd471efc861
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-non-recurring-1.ics
@@ -0,0 +1,10 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+SUMMARY:non-recurring
+DTSTART;VALUE=DATE-TIME:20030919T090000
+DTEND;VALUE=DATE-TIME:20030919T113000
+END:VEVENT
+END:VCALENDAR
+
diff --git a/test/lisp/calendar/icalendar-resources/import-non-recurring-all-day.diary-american b/test/lisp/calendar/icalendar-resources/import-non-recurring-all-day.diary-american
new file mode 100644
index 00000000000..1d4bb6a337e
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-non-recurring-all-day.diary-american
@@ -0,0 +1 @@
+&9/19/2003 non-recurring allday
diff --git a/test/lisp/calendar/icalendar-resources/import-non-recurring-all-day.diary-european b/test/lisp/calendar/icalendar-resources/import-non-recurring-all-day.diary-european
new file mode 100644
index 00000000000..b56c7f4e17f
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-non-recurring-all-day.diary-european
@@ -0,0 +1 @@
+&19/9/2003 non-recurring allday
diff --git a/test/lisp/calendar/icalendar-resources/import-non-recurring-all-day.diary-iso b/test/lisp/calendar/icalendar-resources/import-non-recurring-all-day.diary-iso
new file mode 100644
index 00000000000..f1c70ab34c3
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-non-recurring-all-day.diary-iso
@@ -0,0 +1 @@
+&2003/9/19 non-recurring allday
diff --git a/test/lisp/calendar/icalendar-resources/import-non-recurring-all-day.ics b/test/lisp/calendar/icalendar-resources/import-non-recurring-all-day.ics
new file mode 100644
index 00000000000..4efa8ffa133
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-non-recurring-all-day.ics
@@ -0,0 +1,9 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+SUMMARY:non-recurring allday
+DTSTART;VALUE=DATE-TIME:20030919
+END:VEVENT
+END:VCALENDAR
+
diff --git a/test/lisp/calendar/icalendar-resources/import-non-recurring-another-example.diary-american b/test/lisp/calendar/icalendar-resources/import-non-recurring-another-example.diary-american
new file mode 100644
index 00000000000..2eb8c0ab686
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-non-recurring-another-example.diary-american
@@ -0,0 +1,4 @@
+&11/23/2004 14:45-15:45 another example
+ Status: TENTATIVE
+ Class: PRIVATE
+ UID: 6161a312-3902-11d9-b512-f764153bb28b
diff --git a/test/lisp/calendar/icalendar-resources/import-non-recurring-another-example.diary-european b/test/lisp/calendar/icalendar-resources/import-non-recurring-another-example.diary-european
new file mode 100644
index 00000000000..394eae8bb77
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-non-recurring-another-example.diary-european
@@ -0,0 +1,4 @@
+&23/11/2004 14:45-15:45 another example
+ Status: TENTATIVE
+ Class: PRIVATE
+ UID: 6161a312-3902-11d9-b512-f764153bb28b
diff --git a/test/lisp/calendar/icalendar-resources/import-non-recurring-another-example.diary-iso b/test/lisp/calendar/icalendar-resources/import-non-recurring-another-example.diary-iso
new file mode 100644
index 00000000000..5e8bdf417d5
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-non-recurring-another-example.diary-iso
@@ -0,0 +1,4 @@
+&2004/11/23 14:45-15:45 another example
+ Status: TENTATIVE
+ Class: PRIVATE
+ UID: 6161a312-3902-11d9-b512-f764153bb28b
diff --git a/test/lisp/calendar/icalendar-resources/import-non-recurring-another-example.ics b/test/lisp/calendar/icalendar-resources/import-non-recurring-another-example.ics
new file mode 100644
index 00000000000..b145e418791
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-non-recurring-another-example.ics
@@ -0,0 +1,23 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+UID
+ :6161a312-3902-11d9-b512-f764153bb28b
+SUMMARY
+ :another example
+STATUS
+ :TENTATIVE
+CLASS
+ :PRIVATE
+X-MOZILLA-ALARM-DEFAULT-LENGTH
+ :0
+DTSTART
+ :20041123T144500
+DTEND
+ :20041123T154500
+DTSTAMP
+ :20041118T013641Z
+END:VEVENT
+END:VCALENDAR
+
diff --git a/test/lisp/calendar/icalendar-resources/import-non-recurring-block.diary-american b/test/lisp/calendar/icalendar-resources/import-non-recurring-block.diary-american
new file mode 100644
index 00000000000..b22234229cf
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-non-recurring-block.diary-american
@@ -0,0 +1,4 @@
+&%%(and (diary-block 7 19 2004 8 27 2004)) Sommerferien
+ Status: TENTATIVE
+ Class: PRIVATE
+ UID: 748f2da0-0d9b-11d8-97af-b4ec8686ea61
diff --git a/test/lisp/calendar/icalendar-resources/import-non-recurring-block.diary-european b/test/lisp/calendar/icalendar-resources/import-non-recurring-block.diary-european
new file mode 100644
index 00000000000..8043482442f
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-non-recurring-block.diary-european
@@ -0,0 +1,4 @@
+&%%(and (diary-block 19 7 2004 27 8 2004)) Sommerferien
+ Status: TENTATIVE
+ Class: PRIVATE
+ UID: 748f2da0-0d9b-11d8-97af-b4ec8686ea61
diff --git a/test/lisp/calendar/icalendar-resources/import-non-recurring-block.diary-iso b/test/lisp/calendar/icalendar-resources/import-non-recurring-block.diary-iso
new file mode 100644
index 00000000000..e0f1896114f
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-non-recurring-block.diary-iso
@@ -0,0 +1,4 @@
+&%%(and (diary-block 2004 7 19 2004 8 27)) Sommerferien
+ Status: TENTATIVE
+ Class: PRIVATE
+ UID: 748f2da0-0d9b-11d8-97af-b4ec8686ea61
diff --git a/test/lisp/calendar/icalendar-resources/import-non-recurring-block.ics b/test/lisp/calendar/icalendar-resources/import-non-recurring-block.ics
new file mode 100644
index 00000000000..0c52ba3d66a
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-non-recurring-block.ics
@@ -0,0 +1,16 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+UID:748f2da0-0d9b-11d8-97af-b4ec8686ea61
+SUMMARY:Sommerferien
+STATUS:TENTATIVE
+CLASS:PRIVATE
+X-MOZILLA-ALARM-DEFAULT-UNITS:Minuten
+X-MOZILLA-RECUR-DEFAULT-INTERVAL:0
+DTSTART;VALUE=DATE:20040719
+DTEND;VALUE=DATE:20040828
+DTSTAMP:20031103T011641Z
+END:VEVENT
+END:VCALENDAR
+
diff --git a/test/lisp/calendar/icalendar-resources/import-non-recurring-folded-summary.diary-american b/test/lisp/calendar/icalendar-resources/import-non-recurring-folded-summary.diary-american
new file mode 100644
index 00000000000..2954d0c4fd1
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-non-recurring-folded-summary.diary-american
@@ -0,0 +1,4 @@
+&11/23/2004 14:00-14:30 folded summary
+ Status: TENTATIVE
+ Class: PRIVATE
+ UID: 04979712-3902-11d9-93dd-8f9f4afe08da
diff --git a/test/lisp/calendar/icalendar-resources/import-non-recurring-folded-summary.diary-european b/test/lisp/calendar/icalendar-resources/import-non-recurring-folded-summary.diary-european
new file mode 100644
index 00000000000..7745fc811b4
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-non-recurring-folded-summary.diary-european
@@ -0,0 +1,4 @@
+&23/11/2004 14:00-14:30 folded summary
+ Status: TENTATIVE
+ Class: PRIVATE
+ UID: 04979712-3902-11d9-93dd-8f9f4afe08da
diff --git a/test/lisp/calendar/icalendar-resources/import-non-recurring-folded-summary.diary-iso b/test/lisp/calendar/icalendar-resources/import-non-recurring-folded-summary.diary-iso
new file mode 100644
index 00000000000..8c19a95ed2d
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-non-recurring-folded-summary.diary-iso
@@ -0,0 +1,4 @@
+&2004/11/23 14:00-14:30 folded summary
+ Status: TENTATIVE
+ Class: PRIVATE
+ UID: 04979712-3902-11d9-93dd-8f9f4afe08da
diff --git a/test/lisp/calendar/icalendar-resources/import-non-recurring-folded-summary.ics b/test/lisp/calendar/icalendar-resources/import-non-recurring-folded-summary.ics
new file mode 100644
index 00000000000..e3ecee9dae8
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-non-recurring-folded-summary.ics
@@ -0,0 +1,25 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+UID
+ :04979712-3902-11d9-93dd-8f9f4afe08da
+SUMMARY
+ :folded summary
+STATUS
+ :TENTATIVE
+CLASS
+ :PRIVATE
+X-MOZILLA-ALARM-DEFAULT-LENGTH
+ :0
+DTSTART
+ :20041123T140000
+DTEND
+ :20041123T143000
+DTSTAMP
+ :20041118T013430Z
+LAST-MODIFIED
+ :20041118T013640Z
+END:VEVENT
+END:VCALENDAR
+
diff --git a/test/lisp/calendar/icalendar-resources/import-non-recurring-long-summary.diary-american b/test/lisp/calendar/icalendar-resources/import-non-recurring-long-summary.diary-american
new file mode 100644
index 00000000000..84cd464c568
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-non-recurring-long-summary.diary-american
@@ -0,0 +1 @@
+&9/19/2003 long summary
diff --git a/test/lisp/calendar/icalendar-resources/import-non-recurring-long-summary.diary-european b/test/lisp/calendar/icalendar-resources/import-non-recurring-long-summary.diary-european
new file mode 100644
index 00000000000..5d6524202c3
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-non-recurring-long-summary.diary-european
@@ -0,0 +1 @@
+&19/9/2003 long summary
diff --git a/test/lisp/calendar/icalendar-resources/import-non-recurring-long-summary.diary-iso b/test/lisp/calendar/icalendar-resources/import-non-recurring-long-summary.diary-iso
new file mode 100644
index 00000000000..d2300522d9a
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-non-recurring-long-summary.diary-iso
@@ -0,0 +1 @@
+&2003/9/19 long summary
diff --git a/test/lisp/calendar/icalendar-resources/import-non-recurring-long-summary.ics b/test/lisp/calendar/icalendar-resources/import-non-recurring-long-summary.ics
new file mode 100644
index 00000000000..39ae02f10ca
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-non-recurring-long-summary.ics
@@ -0,0 +1,10 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+SUMMARY:long
+ summary
+DTSTART;VALUE=DATE:20030919
+END:VEVENT
+END:VCALENDAR
+
diff --git a/test/lisp/calendar/icalendar-resources/import-real-world-2003-05-29.diary-american b/test/lisp/calendar/icalendar-resources/import-real-world-2003-05-29.diary-american
new file mode 100644
index 00000000000..e6c8712d254
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-real-world-2003-05-29.diary-american
@@ -0,0 +1,6 @@
+&5/9/2003 07:00-12:00 On-Site Interview
+ Desc: 10:30am - Blah
+ Location: Cccc
+ Organizer: MAILTO:aaaaaaa@aaaaaaa.com
+ Status: CONFIRMED
+ UID: 040000008200E00074C5B7101A82E0080000000080B6DE661216C301000000000000000010000000DB823520692542408ED02D7023F9DFF9
diff --git a/test/lisp/calendar/icalendar-resources/import-real-world-2003-05-29.diary-european b/test/lisp/calendar/icalendar-resources/import-real-world-2003-05-29.diary-european
new file mode 100644
index 00000000000..cecca070a51
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-real-world-2003-05-29.diary-european
@@ -0,0 +1,6 @@
+&9/5/2003 07:00-12:00 On-Site Interview
+ Desc: 10:30am - Blah
+ Location: Cccc
+ Organizer: MAILTO:aaaaaaa@aaaaaaa.com
+ Status: CONFIRMED
+ UID: 040000008200E00074C5B7101A82E0080000000080B6DE661216C301000000000000000010000000DB823520692542408ED02D7023F9DFF9
diff --git a/test/lisp/calendar/icalendar-resources/import-real-world-2003-05-29.ics b/test/lisp/calendar/icalendar-resources/import-real-world-2003-05-29.ics
new file mode 100644
index 00000000000..decc8df5451
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-real-world-2003-05-29.ics
@@ -0,0 +1,54 @@
+BEGIN:VCALENDAR
+METHOD:REQUEST
+PRODID:Microsoft CDO for Microsoft Exchange
+VERSION:2.0
+BEGIN:VTIMEZONE
+TZID:Kolkata, Chennai, Mumbai, New Delhi
+X-MICROSOFT-CDO-TZID:23
+BEGIN:STANDARD
+DTSTART:16010101T000000
+TZOFFSETFROM:+0530
+TZOFFSETTO:+0530
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:16010101T000000
+TZOFFSETFROM:+0530
+TZOFFSETTO:+0530
+END:DAYLIGHT
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20030509T043439Z
+DTSTART;TZID="Kolkata, Chennai, Mumbai, New Delhi":20030509T103000
+SUMMARY:On-Site Interview
+UID:040000008200E00074C5B7101A82E0080000000080B6DE661216C301000000000000000
+ 010000000DB823520692542408ED02D7023F9DFF9
+ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN="Xxxxx
+ xxx Xxxxxxxxxxxx":MAILTO:xxxxxxxx@xxxxxxx.com
+ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN="Yyyyyyy Y
+ yyyy":MAILTO:yyyyyyy@yyyyyyy.com
+ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN="Zzzz Zzzz
+ zz":MAILTO:zzzzzz@zzzzzzz.com
+ORGANIZER;CN="Aaaaaa Aaaaa":MAILTO:aaaaaaa@aaaaaaa.com
+LOCATION:Cccc
+DTEND;TZID="Kolkata, Chennai, Mumbai, New Delhi":20030509T153000
+DESCRIPTION:10:30am - Blah
+SEQUENCE:0
+PRIORITY:5
+CLASS:
+CREATED:20030509T043439Z
+LAST-MODIFIED:20030509T043459Z
+STATUS:CONFIRMED
+TRANSP:OPAQUE
+X-MICROSOFT-CDO-BUSYSTATUS:BUSY
+X-MICROSOFT-CDO-INSTTYPE:0
+X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY
+X-MICROSOFT-CDO-ALLDAYEVENT:FALSE
+X-MICROSOFT-CDO-IMPORTANCE:1
+X-MICROSOFT-CDO-OWNERAPPTID:126441427
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:REMINDER
+TRIGGER;RELATED=START:-PT00H15M00S
+END:VALARM
+END:VEVENT
+END:VCALENDAR
diff --git a/test/lisp/calendar/icalendar-resources/import-real-world-2003-06-18a.diary-american b/test/lisp/calendar/icalendar-resources/import-real-world-2003-06-18a.diary-american
new file mode 100644
index 00000000000..f2c914184e7
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-real-world-2003-06-18a.diary-american
@@ -0,0 +1,6 @@
+&6/23/2003 11:00-12:00 Dress Rehearsal for XXXX-XXXX
+ Desc: 753 Zeichen hier radiert
+ Location: 555 or TN 555-5555 ID 5555 & NochWas (see below)
+ Organizer: MAILTO:xxx@xxxxx.com
+ Status: CONFIRMED
+ UID: 040000008200E00074C5B7101A82E00800000000608AA7DA9835C3010000000000000000100000007C3A6D65EE726E40B7F3D69A23BD567E
diff --git a/test/lisp/calendar/icalendar-resources/import-real-world-2003-06-18a.diary-european b/test/lisp/calendar/icalendar-resources/import-real-world-2003-06-18a.diary-european
new file mode 100644
index 00000000000..89cff58af42
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-real-world-2003-06-18a.diary-european
@@ -0,0 +1,6 @@
+&23/6/2003 11:00-12:00 Dress Rehearsal for XXXX-XXXX
+ Desc: 753 Zeichen hier radiert
+ Location: 555 or TN 555-5555 ID 5555 & NochWas (see below)
+ Organizer: MAILTO:xxx@xxxxx.com
+ Status: CONFIRMED
+ UID: 040000008200E00074C5B7101A82E00800000000608AA7DA9835C3010000000000000000100000007C3A6D65EE726E40B7F3D69A23BD567E
diff --git a/test/lisp/calendar/icalendar-resources/import-real-world-2003-06-18a.ics b/test/lisp/calendar/icalendar-resources/import-real-world-2003-06-18a.ics
new file mode 100644
index 00000000000..6bb5b05af17
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-real-world-2003-06-18a.ics
@@ -0,0 +1,36 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+DTSTAMP:20030618T195512Z
+DTSTART;TZID="Mountain Time (US & Canada)":20030623T110000
+SUMMARY:Dress Rehearsal for XXXX-XXXX
+UID:040000008200E00074C5B7101A82E00800000000608AA7DA9835C301000000000000000
+ 0100000007C3A6D65EE726E40B7F3D69A23BD567E
+ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN="AAAAA,AAA
+ AA (A-AAAAAAA,ex1)":MAILTO:aaaaa_aaaaa@aaaaa.com
+ORGANIZER;CN="ABCD,TECHTRAINING
+ (A-Americas,exgen1)":MAILTO:xxx@xxxxx.com
+LOCATION:555 or TN 555-5555 ID 5555 & NochWas (see below)
+DTEND;TZID="Mountain Time (US & Canada)":20030623T120000
+DESCRIPTION:753 Zeichen hier radiert
+SEQUENCE:0
+PRIORITY:5
+CLASS:
+CREATED:20030618T195518Z
+LAST-MODIFIED:20030618T195527Z
+STATUS:CONFIRMED
+TRANSP:OPAQUE
+X-MICROSOFT-CDO-BUSYSTATUS:BUSY
+X-MICROSOFT-CDO-INSTTYPE:0
+X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY
+X-MICROSOFT-CDO-ALLDAYEVENT:FALSE
+X-MICROSOFT-CDO-IMPORTANCE:1
+X-MICROSOFT-CDO-OWNERAPPTID:1022519251
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:REMINDER
+TRIGGER;RELATED=START:-PT00H15M00S
+END:VALARM
+END:VEVENT
+END:VCALENDAR
diff --git a/test/lisp/calendar/icalendar-resources/import-real-world-2003-06-18b.diary-american b/test/lisp/calendar/icalendar-resources/import-real-world-2003-06-18b.diary-american
new file mode 100644
index 00000000000..2c0774cdd83
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-real-world-2003-06-18b.diary-american
@@ -0,0 +1,6 @@
+&6/23/2003 17:00-18:00 Updated: Dress Rehearsal for ABC01-15
+ Desc: Viele Zeichen standen hier früher
+ Location: 123 or TN 123-1234 ID abcd & SonstWo (see below)
+ Organizer: MAILTO:bbb@bbbbb.com
+ Status: CONFIRMED
+ UID: 040000008200E00074C5B7101A82E00800000000608AA7DA9835C3010000000000000000100000007C3A6D65EE726E40B7F3D69A23BD567E
diff --git a/test/lisp/calendar/icalendar-resources/import-real-world-2003-06-18b.diary-european b/test/lisp/calendar/icalendar-resources/import-real-world-2003-06-18b.diary-european
new file mode 100644
index 00000000000..95aac168699
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-real-world-2003-06-18b.diary-european
@@ -0,0 +1,6 @@
+&23/6/2003 17:00-18:00 Updated: Dress Rehearsal for ABC01-15
+ Desc: Viele Zeichen standen hier früher
+ Location: 123 or TN 123-1234 ID abcd & SonstWo (see below)
+ Organizer: MAILTO:bbb@bbbbb.com
+ Status: CONFIRMED
+ UID: 040000008200E00074C5B7101A82E00800000000608AA7DA9835C3010000000000000000100000007C3A6D65EE726E40B7F3D69A23BD567E
diff --git a/test/lisp/calendar/icalendar-resources/import-real-world-2003-06-18b.ics b/test/lisp/calendar/icalendar-resources/import-real-world-2003-06-18b.ics
new file mode 100644
index 00000000000..1523135adf3
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-real-world-2003-06-18b.ics
@@ -0,0 +1,55 @@
+BEGIN:VCALENDAR
+METHOD:REQUEST
+PRODID:Microsoft CDO for Microsoft Exchange
+VERSION:2.0
+BEGIN:VTIMEZONE
+TZID:Mountain Time (US & Canada)
+X-MICROSOFT-CDO-TZID:12
+BEGIN:STANDARD
+DTSTART:16010101T020000
+TZOFFSETFROM:-0600
+TZOFFSETTO:-0700
+RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=10;BYDAY=-1SU
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:16010101T020000
+TZOFFSETFROM:-0700
+TZOFFSETTO:-0600
+RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=4;BYDAY=1SU
+END:DAYLIGHT
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20030618T230323Z
+DTSTART;TZID="Mountain Time (US & Canada)":20030623T090000
+SUMMARY:Updated: Dress Rehearsal for ABC01-15
+UID:040000008200E00074C5B7101A82E00800000000608AA7DA9835C301000000000000000
+ 0100000007C3A6D65EE726E40B7F3D69A23BD567E
+ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;X-REPLYTIME=20030618T20
+ 0700Z;RSVP=TRUE;CN="AAAAA,AAAAAA
+\(A-AAAAAAA,ex1)":MAILTO:aaaaaa_aaaaa@aaaaa
+ .com
+ORGANIZER;CN="ABCD,TECHTRAINING
+\(A-Americas,exgen1)":MAILTO:bbb@bbbbb.com
+LOCATION:123 or TN 123-1234 ID abcd & SonstWo (see below)
+DTEND;TZID="Mountain Time (US & Canada)":20030623T100000
+DESCRIPTION:Viele Zeichen standen hier früher
+SEQUENCE:0
+PRIORITY:5
+CLASS:
+CREATED:20030618T230326Z
+LAST-MODIFIED:20030618T230335Z
+STATUS:CONFIRMED
+TRANSP:OPAQUE
+X-MICROSOFT-CDO-BUSYSTATUS:BUSY
+X-MICROSOFT-CDO-INSTTYPE:0
+X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY
+X-MICROSOFT-CDO-ALLDAYEVENT:FALSE
+X-MICROSOFT-CDO-IMPORTANCE:1
+X-MICROSOFT-CDO-OWNERAPPTID:1022519251
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:REMINDER
+TRIGGER;RELATED=START:-PT00H15M00S
+END:VALARM
+END:VEVENT
+END:VCALENDAR \ No newline at end of file
diff --git a/test/lisp/calendar/icalendar-resources/import-real-world-2004-11-19.diary-american b/test/lisp/calendar/icalendar-resources/import-real-world-2004-11-19.diary-american
new file mode 100644
index 00000000000..a986f700ba2
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-real-world-2004-11-19.diary-american
@@ -0,0 +1,19 @@
+&11/23/2004 14:00-14:30 Jjjjj & Wwwww
+ Status: TENTATIVE
+ Class: PRIVATE
+&11/23/2004 14:45-15:45 BB Aaaaaaaa Bbbbb
+ Status: TENTATIVE
+ Class: PRIVATE
+&11/23/2004 11:00-12:00 Hhhhhhhh
+ Status: TENTATIVE
+ Class: PRIVATE
+&%%(and (diary-cyclic 14 11 12 2004)) 14:00-18:30 MMM Aaaaaaaaa
+ Status: TENTATIVE
+ Class: PRIVATE
+&%%(and (diary-block 11 19 2004 11 19 2004)) Rrrr/Cccccc ii Aaaaaaaa
+ Desc: Vvvvv Rrrr aaa Cccccc
+ Status: TENTATIVE
+ Class: PRIVATE
+&%%(and (diary-cyclic 7 11 1 2004)) Wwww aa hhhh
+ Status: TENTATIVE
+ Class: PRIVATE
diff --git a/test/lisp/calendar/icalendar-resources/import-real-world-2004-11-19.diary-european b/test/lisp/calendar/icalendar-resources/import-real-world-2004-11-19.diary-european
new file mode 100644
index 00000000000..cbfe99eb8e3
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-real-world-2004-11-19.diary-european
@@ -0,0 +1,19 @@
+&23/11/2004 14:00-14:30 Jjjjj & Wwwww
+ Status: TENTATIVE
+ Class: PRIVATE
+&23/11/2004 14:45-15:45 BB Aaaaaaaa Bbbbb
+ Status: TENTATIVE
+ Class: PRIVATE
+&23/11/2004 11:00-12:00 Hhhhhhhh
+ Status: TENTATIVE
+ Class: PRIVATE
+&%%(and (diary-cyclic 14 12 11 2004)) 14:00-18:30 MMM Aaaaaaaaa
+ Status: TENTATIVE
+ Class: PRIVATE
+&%%(and (diary-block 19 11 2004 19 11 2004)) Rrrr/Cccccc ii Aaaaaaaa
+ Desc: Vvvvv Rrrr aaa Cccccc
+ Status: TENTATIVE
+ Class: PRIVATE
+&%%(and (diary-cyclic 7 1 11 2004)) Wwww aa hhhh
+ Status: TENTATIVE
+ Class: PRIVATE
diff --git a/test/lisp/calendar/icalendar-resources/import-real-world-2004-11-19.ics b/test/lisp/calendar/icalendar-resources/import-real-world-2004-11-19.ics
new file mode 100644
index 00000000000..9edb682fcad
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-real-world-2004-11-19.ics
@@ -0,0 +1,120 @@
+BEGIN:VCALENDAR
+VERSION
+ :2.0
+PRODID
+ :-//Mozilla.org/NONSGML Mozilla Calendar V1.0//EN
+BEGIN:VEVENT
+SUMMARY
+ :Jjjjj & Wwwww
+STATUS
+ :TENTATIVE
+CLASS
+ :PRIVATE
+X-MOZILLA-ALARM-DEFAULT-LENGTH
+ :0
+DTSTART
+ :20041123T140000
+DTEND
+ :20041123T143000
+DTSTAMP
+ :20041118T013430Z
+LAST-MODIFIED
+ :20041118T013640Z
+END:VEVENT
+BEGIN:VEVENT
+SUMMARY
+ :BB Aaaaaaaa Bbbbb
+STATUS
+ :TENTATIVE
+CLASS
+ :PRIVATE
+X-MOZILLA-ALARM-DEFAULT-LENGTH
+ :0
+DTSTART
+ :20041123T144500
+DTEND
+ :20041123T154500
+DTSTAMP
+ :20041118T013641Z
+END:VEVENT
+BEGIN:VEVENT
+SUMMARY
+ :Hhhhhhhh
+STATUS
+ :TENTATIVE
+CLASS
+ :PRIVATE
+X-MOZILLA-ALARM-DEFAULT-LENGTH
+ :0
+DTSTART
+ :20041123T110000
+DTEND
+ :20041123T120000
+DTSTAMP
+ :20041118T013831Z
+END:VEVENT
+BEGIN:VEVENT
+SUMMARY
+ :MMM Aaaaaaaaa
+STATUS
+ :TENTATIVE
+CLASS
+ :PRIVATE
+X-MOZILLA-ALARM-DEFAULT-LENGTH
+ :0
+X-MOZILLA-RECUR-DEFAULT-INTERVAL
+ :2
+RRULE
+ :FREQ=WEEKLY;INTERVAL=2;BYDAY=FR
+DTSTART
+ :20041112T140000
+DTEND
+ :20041112T183000
+DTSTAMP
+ :20041118T014117Z
+END:VEVENT
+BEGIN:VEVENT
+SUMMARY
+ :Rrrr/Cccccc ii Aaaaaaaa
+DESCRIPTION
+ :Vvvvv Rrrr aaa Cccccc
+STATUS
+ :TENTATIVE
+CLASS
+ :PRIVATE
+X-MOZILLA-ALARM-DEFAULT-LENGTH
+ :0
+DTSTART
+ ;VALUE=DATE
+ :20041119
+DTEND
+ ;VALUE=DATE
+ :20041120
+DTSTAMP
+ :20041118T013107Z
+LAST-MODIFIED
+ :20041118T014203Z
+END:VEVENT
+BEGIN:VEVENT
+SUMMARY
+ :Wwww aa hhhh
+STATUS
+ :TENTATIVE
+CLASS
+ :PRIVATE
+X-MOZILLA-ALARM-DEFAULT-LENGTH
+ :0
+RRULE
+ :FREQ=WEEKLY;INTERVAL=1;BYDAY=MO
+DTSTART
+ ;VALUE=DATE
+ :20041101
+DTEND
+ ;VALUE=DATE
+ :20041102
+DTSTAMP
+ :20041118T014045Z
+LAST-MODIFIED
+ :20041118T023846Z
+END:VEVENT
+END:VCALENDAR
diff --git a/test/lisp/calendar/icalendar-resources/import-real-world-2005-02-07.diary-american b/test/lisp/calendar/icalendar-resources/import-real-world-2005-02-07.diary-american
new file mode 100644
index 00000000000..ce7d835d96b
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-real-world-2005-02-07.diary-american
@@ -0,0 +1,5 @@
+&%%(and (diary-block 2 6 2005 2 6 2005)) Waitangi Day
+ Desc: abcdef
+ Status: CONFIRMED
+ Class: PRIVATE
+ UID: b60d398e-1dd1-11b2-a159-cf8cb05139f4
diff --git a/test/lisp/calendar/icalendar-resources/import-real-world-2005-02-07.diary-european b/test/lisp/calendar/icalendar-resources/import-real-world-2005-02-07.diary-european
new file mode 100644
index 00000000000..3a52b0ab271
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-real-world-2005-02-07.diary-european
@@ -0,0 +1,5 @@
+&%%(and (diary-block 6 2 2005 6 2 2005)) Waitangi Day
+ Desc: abcdef
+ Status: CONFIRMED
+ Class: PRIVATE
+ UID: b60d398e-1dd1-11b2-a159-cf8cb05139f4
diff --git a/test/lisp/calendar/icalendar-resources/import-real-world-2005-02-07.ics b/test/lisp/calendar/icalendar-resources/import-real-world-2005-02-07.ics
new file mode 100644
index 00000000000..9eec71fe751
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-real-world-2005-02-07.ics
@@ -0,0 +1,26 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+UID
+ :b60d398e-1dd1-11b2-a159-cf8cb05139f4
+SUMMARY
+ :Waitangi Day
+DESCRIPTION
+ :abcdef
+CATEGORIES
+ :Public Holiday
+STATUS
+ :CONFIRMED
+CLASS
+ :PRIVATE
+DTSTART
+ ;VALUE=DATE
+ :20050206
+DTEND
+ ;VALUE=DATE
+ :20050207
+DTSTAMP
+ :20050128T011209Z
+END:VEVENT
+END:VCALENDAR
diff --git a/test/lisp/calendar/icalendar-resources/import-real-world-2005-03-01.diary-american b/test/lisp/calendar/icalendar-resources/import-real-world-2005-03-01.diary-american
new file mode 100644
index 00000000000..23c93d45d9a
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-real-world-2005-03-01.diary-american
@@ -0,0 +1,2 @@
+&%%(and (diary-block 2 17 2005 2 23 2005)) Hhhhhh Aaaaa ii Aaaaaaaa
+ UID: 6AFA7558-6994-11D9-8A3A-000A95A0E830-RID
diff --git a/test/lisp/calendar/icalendar-resources/import-real-world-2005-03-01.diary-european b/test/lisp/calendar/icalendar-resources/import-real-world-2005-03-01.diary-european
new file mode 100644
index 00000000000..106e9f3cdd0
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-real-world-2005-03-01.diary-european
@@ -0,0 +1,2 @@
+&%%(and (diary-block 17 2 2005 23 2 2005)) Hhhhhh Aaaaa ii Aaaaaaaa
+ UID: 6AFA7558-6994-11D9-8A3A-000A95A0E830-RID
diff --git a/test/lisp/calendar/icalendar-resources/import-real-world-2005-03-01.ics b/test/lisp/calendar/icalendar-resources/import-real-world-2005-03-01.ics
new file mode 100644
index 00000000000..ed9faa9b0bd
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-real-world-2005-03-01.ics
@@ -0,0 +1,11 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+DTSTART;VALUE=DATE:20050217
+SUMMARY:Hhhhhh Aaaaa ii Aaaaaaaa
+UID:6AFA7558-6994-11D9-8A3A-000A95A0E830-RID
+DTSTAMP:20050118T210335Z
+DURATION:P7D
+END:VEVENT
+END:VCALENDAR
diff --git a/test/lisp/calendar/icalendar-resources/import-real-world-no-dst.diary-american b/test/lisp/calendar/icalendar-resources/import-real-world-no-dst.diary-american
new file mode 100644
index 00000000000..290edb88760
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-real-world-no-dst.diary-american
@@ -0,0 +1,4 @@
+&11/16/2014 04:30-05:30 NoDST
+ Desc: Test event from timezone without DST
+ Location: Everywhere
+ UID: 20141116T171439Z-678877132@marudot.com
diff --git a/test/lisp/calendar/icalendar-resources/import-real-world-no-dst.diary-european b/test/lisp/calendar/icalendar-resources/import-real-world-no-dst.diary-european
new file mode 100644
index 00000000000..c56b7a6547a
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-real-world-no-dst.diary-european
@@ -0,0 +1,4 @@
+&16/11/2014 04:30-05:30 NoDST
+ Desc: Test event from timezone without DST
+ Location: Everywhere
+ UID: 20141116T171439Z-678877132@marudot.com
diff --git a/test/lisp/calendar/icalendar-resources/import-real-world-no-dst.ics b/test/lisp/calendar/icalendar-resources/import-real-world-no-dst.ics
new file mode 100644
index 00000000000..5f147af4f37
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-real-world-no-dst.ics
@@ -0,0 +1,26 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//www.marudot.com//iCal Event Maker
+X-WR-CALNAME:Test
+CALSCALE:GREGORIAN
+BEGIN:VTIMEZONE
+TZID:Asia/Tehran
+TZURL:http://tzurl.org/zoneinfo-outlook/Asia/Tehran
+X-LIC-LOCATION:Asia/Tehran
+BEGIN:STANDARD
+TZOFFSETFROM:+0330
+TZOFFSETTO:+0330
+TZNAME:IRST
+DTSTART:19700101T000000
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20141116T171439Z
+UID:20141116T171439Z-678877132@marudot.com
+DTSTART;TZID="Asia/Tehran":20141116T070000
+DTEND;TZID="Asia/Tehran":20141116T080000
+SUMMARY:NoDST
+DESCRIPTION:Test event from timezone without DST
+LOCATION:Everywhere
+END:VEVENT
+END:VCALENDAR \ No newline at end of file
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-american b/test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-american
new file mode 100644
index 00000000000..2f7026a0bde
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-american
@@ -0,0 +1 @@
+&%%(diary-anniversary 8 15 2003) Maria Himmelfahrt
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-european b/test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-european
new file mode 100644
index 00000000000..fa652dbb92e
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-european
@@ -0,0 +1 @@
+&%%(diary-anniversary 15 8 2003) Maria Himmelfahrt
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-iso b/test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-iso
new file mode 100644
index 00000000000..803dd36de0a
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-iso
@@ -0,0 +1 @@
+&%%(diary-anniversary 2003 8 15) Maria Himmelfahrt
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-anniversary.ics b/test/lisp/calendar/icalendar-resources/import-rrule-anniversary.ics
new file mode 100644
index 00000000000..2996f494167
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-anniversary.ics
@@ -0,0 +1,11 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+DTSTART;VALUE=DATE:20040815
+DTEND;VALUE=DATE:20040816
+SUMMARY:Maria Himmelfahrt
+RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=8
+END:VEVENT
+END:VCALENDAR
+
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-bi-weekly.diary-american b/test/lisp/calendar/icalendar-resources/import-rrule-count-bi-weekly.diary-american
new file mode 100644
index 00000000000..84b6d109953
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-bi-weekly.diary-american
@@ -0,0 +1 @@
+&%%(and (diary-cyclic 14 9 19 2003) (diary-block 9 19 2003 10 31 2003)) 09:00-11:30 rrule count bi-weekly 3 times
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-bi-weekly.diary-european b/test/lisp/calendar/icalendar-resources/import-rrule-count-bi-weekly.diary-european
new file mode 100644
index 00000000000..0bebdf8872f
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-bi-weekly.diary-european
@@ -0,0 +1 @@
+&%%(and (diary-cyclic 14 19 9 2003) (diary-block 19 9 2003 31 10 2003)) 09:00-11:30 rrule count bi-weekly 3 times
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-bi-weekly.diary-iso b/test/lisp/calendar/icalendar-resources/import-rrule-count-bi-weekly.diary-iso
new file mode 100644
index 00000000000..11429081abe
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-bi-weekly.diary-iso
@@ -0,0 +1 @@
+&%%(and (diary-cyclic 14 2003 9 19) (diary-block 2003 9 19 2003 10 31)) 09:00-11:30 rrule count bi-weekly 3 times
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-bi-weekly.ics b/test/lisp/calendar/icalendar-resources/import-rrule-count-bi-weekly.ics
new file mode 100644
index 00000000000..888b85bb331
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-bi-weekly.ics
@@ -0,0 +1,11 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+SUMMARY:rrule count bi-weekly 3 times
+DTSTART;VALUE=DATE-TIME:20030919T090000
+DTEND;VALUE=DATE-TIME:20030919T113000
+RRULE:FREQ=WEEKLY;COUNT=3;INTERVAL=2
+END:VEVENT
+END:VCALENDAR
+
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-daily-long.diary-american b/test/lisp/calendar/icalendar-resources/import-rrule-count-daily-long.diary-american
new file mode 100644
index 00000000000..23fe9fcaf32
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-daily-long.diary-american
@@ -0,0 +1 @@
+&%%(and (diary-cyclic 1 9 19 2003) (diary-block 9 19 2003 10 2 2003)) 09:00-11:30 rrule count daily long
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-daily-long.diary-european b/test/lisp/calendar/icalendar-resources/import-rrule-count-daily-long.diary-european
new file mode 100644
index 00000000000..0d4ab669058
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-daily-long.diary-european
@@ -0,0 +1 @@
+&%%(and (diary-cyclic 1 19 9 2003) (diary-block 19 9 2003 2 10 2003)) 09:00-11:30 rrule count daily long
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-daily-long.diary-iso b/test/lisp/calendar/icalendar-resources/import-rrule-count-daily-long.diary-iso
new file mode 100644
index 00000000000..8cecda5c879
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-daily-long.diary-iso
@@ -0,0 +1 @@
+&%%(and (diary-cyclic 1 2003 9 19) (diary-block 2003 9 19 2003 10 2)) 09:00-11:30 rrule count daily long
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-daily-long.ics b/test/lisp/calendar/icalendar-resources/import-rrule-count-daily-long.ics
new file mode 100644
index 00000000000..73df19a8196
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-daily-long.ics
@@ -0,0 +1,11 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+SUMMARY:rrule count daily long
+DTSTART;VALUE=DATE-TIME:20030919T090000
+DTEND;VALUE=DATE-TIME:20030919T113000
+RRULE:FREQ=DAILY;COUNT=14;INTERVAL=1
+END:VEVENT
+END:VCALENDAR
+
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-daily-short.diary-american b/test/lisp/calendar/icalendar-resources/import-rrule-count-daily-short.diary-american
new file mode 100644
index 00000000000..d69bb08c318
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-daily-short.diary-american
@@ -0,0 +1 @@
+&%%(and (diary-cyclic 1 9 19 2003) (diary-block 9 19 2003 9 19 2003)) 09:00-11:30 rrule count daily short
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-daily-short.diary-european b/test/lisp/calendar/icalendar-resources/import-rrule-count-daily-short.diary-european
new file mode 100644
index 00000000000..33a1ce4cf51
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-daily-short.diary-european
@@ -0,0 +1 @@
+&%%(and (diary-cyclic 1 19 9 2003) (diary-block 19 9 2003 19 9 2003)) 09:00-11:30 rrule count daily short
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-daily-short.diary-iso b/test/lisp/calendar/icalendar-resources/import-rrule-count-daily-short.diary-iso
new file mode 100644
index 00000000000..a06bcba0dc1
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-daily-short.diary-iso
@@ -0,0 +1 @@
+&%%(and (diary-cyclic 1 2003 9 19) (diary-block 2003 9 19 2003 9 19)) 09:00-11:30 rrule count daily short
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-daily-short.ics b/test/lisp/calendar/icalendar-resources/import-rrule-count-daily-short.ics
new file mode 100644
index 00000000000..92ffe8be654
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-daily-short.ics
@@ -0,0 +1,11 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+SUMMARY:rrule count daily short
+DTSTART;VALUE=DATE-TIME:20030919T090000
+DTEND;VALUE=DATE-TIME:20030919T113000
+RRULE:FREQ=DAILY;COUNT=1;INTERVAL=1
+END:VEVENT
+END:VCALENDAR
+
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-month.diary-american b/test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-month.diary-american
new file mode 100644
index 00000000000..4ce8ef842f8
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-month.diary-american
@@ -0,0 +1 @@
+&%%(and (diary-date t 19 t) (diary-block 9 19 2003 5 19 2004)) 09:00-11:30 rrule count every second month
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-month.diary-european b/test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-month.diary-european
new file mode 100644
index 00000000000..09ec3756295
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-month.diary-european
@@ -0,0 +1 @@
+&%%(and (diary-date 19 t t) (diary-block 19 9 2003 19 5 2004)) 09:00-11:30 rrule count every second month
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-month.diary-iso b/test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-month.diary-iso
new file mode 100644
index 00000000000..ae6feb70d4c
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-month.diary-iso
@@ -0,0 +1 @@
+&%%(and (diary-date t t 19) (diary-block 2003 9 19 2004 5 19)) 09:00-11:30 rrule count every second month
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-month.ics b/test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-month.ics
new file mode 100644
index 00000000000..3b27b665498
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-month.ics
@@ -0,0 +1,11 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+SUMMARY:rrule count every second month
+DTSTART;VALUE=DATE-TIME:20030919T090000
+DTEND;VALUE=DATE-TIME:20030919T113000
+RRULE:FREQ=MONTHLY;INTERVAL=2;COUNT=5
+END:VEVENT
+END:VCALENDAR
+
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-year.diary-american b/test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-year.diary-american
new file mode 100644
index 00000000000..99543aa9596
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-year.diary-american
@@ -0,0 +1 @@
+&%%(and (diary-date 9 19 t) (diary-block 9 19 2003 9 19 2011)) 09:00-11:30 rrule count every second year
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-year.diary-european b/test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-year.diary-european
new file mode 100644
index 00000000000..3b330886ce0
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-year.diary-european
@@ -0,0 +1 @@
+&%%(and (diary-date 19 9 t) (diary-block 19 9 2003 19 9 2011)) 09:00-11:30 rrule count every second year
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-year.diary-iso b/test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-year.diary-iso
new file mode 100644
index 00000000000..16af52ea91c
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-year.diary-iso
@@ -0,0 +1 @@
+&%%(and (diary-date t 9 19) (diary-block 2003 9 19 2011 9 19)) 09:00-11:30 rrule count every second year
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-year.ics b/test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-year.ics
new file mode 100644
index 00000000000..ce21c34d09a
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-every-second-year.ics
@@ -0,0 +1,10 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+SUMMARY:rrule count every second year
+DTSTART;VALUE=DATE-TIME:20030919T090000
+DTEND;VALUE=DATE-TIME:20030919T113000
+RRULE:FREQ=YEARLY;INTERVAL=2;COUNT=5
+END:VEVENT
+END:VCALENDAR
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-monthly.diary-american b/test/lisp/calendar/icalendar-resources/import-rrule-count-monthly.diary-american
new file mode 100644
index 00000000000..ad5ca0b0ed4
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-monthly.diary-american
@@ -0,0 +1 @@
+&%%(and (diary-date t 19 t) (diary-block 9 19 2003 1 19 2004)) 09:00-11:30 rrule count monthly
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-monthly.diary-european b/test/lisp/calendar/icalendar-resources/import-rrule-count-monthly.diary-european
new file mode 100644
index 00000000000..709de3a3fd5
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-monthly.diary-european
@@ -0,0 +1 @@
+&%%(and (diary-date 19 t t) (diary-block 19 9 2003 19 1 2004)) 09:00-11:30 rrule count monthly
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-monthly.diary-iso b/test/lisp/calendar/icalendar-resources/import-rrule-count-monthly.diary-iso
new file mode 100644
index 00000000000..9fc2a2def94
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-monthly.diary-iso
@@ -0,0 +1 @@
+&%%(and (diary-date t t 19) (diary-block 2003 9 19 2004 1 19)) 09:00-11:30 rrule count monthly
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-monthly.ics b/test/lisp/calendar/icalendar-resources/import-rrule-count-monthly.ics
new file mode 100644
index 00000000000..3391ca24252
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-monthly.ics
@@ -0,0 +1,11 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+SUMMARY:rrule count monthly
+DTSTART;VALUE=DATE-TIME:20030919T090000
+DTEND;VALUE=DATE-TIME:20030919T113000
+RRULE:FREQ=MONTHLY;INTERVAL=1;COUNT=5
+END:VEVENT
+END:VCALENDAR
+
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-yearly.diary-american b/test/lisp/calendar/icalendar-resources/import-rrule-count-yearly.diary-american
new file mode 100644
index 00000000000..8c1f95b0c05
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-yearly.diary-american
@@ -0,0 +1 @@
+&%%(and (diary-date 9 19 t) (diary-block 9 19 2003 9 19 2007)) 09:00-11:30 rrule count yearly
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-yearly.diary-european b/test/lisp/calendar/icalendar-resources/import-rrule-count-yearly.diary-european
new file mode 100644
index 00000000000..e216e224eae
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-yearly.diary-european
@@ -0,0 +1 @@
+&%%(and (diary-date 19 9 t) (diary-block 19 9 2003 19 9 2007)) 09:00-11:30 rrule count yearly
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-yearly.diary-iso b/test/lisp/calendar/icalendar-resources/import-rrule-count-yearly.diary-iso
new file mode 100644
index 00000000000..3801192ee60
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-yearly.diary-iso
@@ -0,0 +1 @@
+&%%(and (diary-date t 9 19) (diary-block 2003 9 19 2007 9 19)) 09:00-11:30 rrule count yearly
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-count-yearly.ics b/test/lisp/calendar/icalendar-resources/import-rrule-count-yearly.ics
new file mode 100644
index 00000000000..d8569933e0c
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-count-yearly.ics
@@ -0,0 +1,11 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+SUMMARY:rrule count yearly
+DTSTART;VALUE=DATE-TIME:20030919T090000
+DTEND;VALUE=DATE-TIME:20030919T113000
+RRULE:FREQ=YEARLY;INTERVAL=1;COUNT=5
+END:VEVENT
+END:VCALENDAR
+
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-daily-two-day.diary-american b/test/lisp/calendar/icalendar-resources/import-rrule-daily-two-day.diary-american
new file mode 100644
index 00000000000..495fca5f8df
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-daily-two-day.diary-american
@@ -0,0 +1 @@
+&%%(and (diary-cyclic 2 9 19 2003)) 09:00-11:30 rrule daily
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-daily-two-day.diary-european b/test/lisp/calendar/icalendar-resources/import-rrule-daily-two-day.diary-european
new file mode 100644
index 00000000000..61db14ab24a
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-daily-two-day.diary-european
@@ -0,0 +1 @@
+&%%(and (diary-cyclic 2 19 9 2003)) 09:00-11:30 rrule daily
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-daily-two-day.diary-iso b/test/lisp/calendar/icalendar-resources/import-rrule-daily-two-day.diary-iso
new file mode 100644
index 00000000000..0e0a4b19781
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-daily-two-day.diary-iso
@@ -0,0 +1 @@
+&%%(and (diary-cyclic 2 2003 9 19)) 09:00-11:30 rrule daily
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-daily-two-day.ics b/test/lisp/calendar/icalendar-resources/import-rrule-daily-two-day.ics
new file mode 100644
index 00000000000..8c9cb3b2845
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-daily-two-day.ics
@@ -0,0 +1,10 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+SUMMARY:rrule daily
+DTSTART;VALUE=DATE-TIME:20030919T090000
+DTEND;VALUE=DATE-TIME:20030919T113000
+RRULE:FREQ=DAILY;INTERVAL=2
+END:VEVENT
+END:VCALENDAR
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-daily-with-exceptions.diary-american b/test/lisp/calendar/icalendar-resources/import-rrule-daily-with-exceptions.diary-american
new file mode 100644
index 00000000000..83e5f582d5f
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-daily-with-exceptions.diary-american
@@ -0,0 +1 @@
+&%%(and (not (diary-date 9 25 2003)) (not (diary-date 9 21 2003)) (diary-cyclic 2 9 19 2003)) 09:00-11:30 rrule daily with exceptions
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-daily-with-exceptions.diary-european b/test/lisp/calendar/icalendar-resources/import-rrule-daily-with-exceptions.diary-european
new file mode 100644
index 00000000000..a3c7fdd4177
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-daily-with-exceptions.diary-european
@@ -0,0 +1 @@
+&%%(and (not (diary-date 25 9 2003)) (not (diary-date 21 9 2003)) (diary-cyclic 2 19 9 2003)) 09:00-11:30 rrule daily with exceptions
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-daily-with-exceptions.diary-iso b/test/lisp/calendar/icalendar-resources/import-rrule-daily-with-exceptions.diary-iso
new file mode 100644
index 00000000000..88b4c892d16
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-daily-with-exceptions.diary-iso
@@ -0,0 +1 @@
+&%%(and (not (diary-date 2003 9 25)) (not (diary-date 2003 9 21)) (diary-cyclic 2 2003 9 19)) 09:00-11:30 rrule daily with exceptions
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-daily-with-exceptions.ics b/test/lisp/calendar/icalendar-resources/import-rrule-daily-with-exceptions.ics
new file mode 100644
index 00000000000..5284bf42d8b
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-daily-with-exceptions.ics
@@ -0,0 +1,12 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+SUMMARY:rrule daily with exceptions
+DTSTART;VALUE=DATE-TIME:20030919T090000
+DTEND;VALUE=DATE-TIME:20030919T113000
+RRULE:FREQ=DAILY;INTERVAL=2
+EXDATE:20030921,20030925
+END:VEVENT
+END:VCALENDAR
+
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-daily.diary-american b/test/lisp/calendar/icalendar-resources/import-rrule-daily.diary-american
new file mode 100644
index 00000000000..9213270fa41
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-daily.diary-american
@@ -0,0 +1 @@
+&%%(and (diary-cyclic 1 9 19 2003)) 09:00-11:30 rrule daily
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-daily.diary-european b/test/lisp/calendar/icalendar-resources/import-rrule-daily.diary-european
new file mode 100644
index 00000000000..2c70cd7da55
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-daily.diary-european
@@ -0,0 +1 @@
+&%%(and (diary-cyclic 1 19 9 2003)) 09:00-11:30 rrule daily
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-daily.diary-iso b/test/lisp/calendar/icalendar-resources/import-rrule-daily.diary-iso
new file mode 100644
index 00000000000..b201cb44308
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-daily.diary-iso
@@ -0,0 +1 @@
+&%%(and (diary-cyclic 1 2003 9 19)) 09:00-11:30 rrule daily
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-daily.ics b/test/lisp/calendar/icalendar-resources/import-rrule-daily.ics
new file mode 100644
index 00000000000..6d013b0b4f6
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-daily.ics
@@ -0,0 +1,11 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+SUMMARY:rrule daily
+DTSTART;VALUE=DATE-TIME:20030919T090000
+DTEND;VALUE=DATE-TIME:20030919T113000
+RRULE:FREQ=DAILY;
+END:VEVENT
+END:VCALENDAR
+
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-monthly-no-end.diary-american b/test/lisp/calendar/icalendar-resources/import-rrule-monthly-no-end.diary-american
new file mode 100644
index 00000000000..bc5453fe425
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-monthly-no-end.diary-american
@@ -0,0 +1 @@
+&%%(and (diary-date t 19 t) (diary-block 9 19 2003 1 1 9999)) 09:00-11:30 rrule monthly no end
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-monthly-no-end.diary-european b/test/lisp/calendar/icalendar-resources/import-rrule-monthly-no-end.diary-european
new file mode 100644
index 00000000000..f071519701d
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-monthly-no-end.diary-european
@@ -0,0 +1 @@
+&%%(and (diary-date 19 t t) (diary-block 19 9 2003 1 1 9999)) 09:00-11:30 rrule monthly no end
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-monthly-no-end.diary-iso b/test/lisp/calendar/icalendar-resources/import-rrule-monthly-no-end.diary-iso
new file mode 100644
index 00000000000..3709e933337
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-monthly-no-end.diary-iso
@@ -0,0 +1 @@
+&%%(and (diary-date t t 19) (diary-block 2003 9 19 9999 1 1)) 09:00-11:30 rrule monthly no end
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-monthly-no-end.ics b/test/lisp/calendar/icalendar-resources/import-rrule-monthly-no-end.ics
new file mode 100644
index 00000000000..b871658600a
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-monthly-no-end.ics
@@ -0,0 +1,11 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+SUMMARY:rrule monthly no end
+DTSTART;VALUE=DATE-TIME:20030919T090000
+DTEND;VALUE=DATE-TIME:20030919T113000
+RRULE:FREQ=MONTHLY;
+END:VEVENT
+END:VCALENDAR
+
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-monthly-with-end.diary-american b/test/lisp/calendar/icalendar-resources/import-rrule-monthly-with-end.diary-american
new file mode 100644
index 00000000000..638ab8b2327
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-monthly-with-end.diary-american
@@ -0,0 +1 @@
+&%%(and (diary-date t 19 t) (diary-block 9 19 2003 8 19 2005)) 09:00-11:30 rrule monthly with end
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-monthly-with-end.diary-european b/test/lisp/calendar/icalendar-resources/import-rrule-monthly-with-end.diary-european
new file mode 100644
index 00000000000..c70cde25f32
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-monthly-with-end.diary-european
@@ -0,0 +1 @@
+&%%(and (diary-date 19 t t) (diary-block 19 9 2003 19 8 2005)) 09:00-11:30 rrule monthly with end
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-monthly-with-end.diary-iso b/test/lisp/calendar/icalendar-resources/import-rrule-monthly-with-end.diary-iso
new file mode 100644
index 00000000000..ee51a2142a4
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-monthly-with-end.diary-iso
@@ -0,0 +1 @@
+&%%(and (diary-date t t 19) (diary-block 2003 9 19 2005 8 19)) 09:00-11:30 rrule monthly with end
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-monthly-with-end.ics b/test/lisp/calendar/icalendar-resources/import-rrule-monthly-with-end.ics
new file mode 100644
index 00000000000..d8a1fe2e5af
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-monthly-with-end.ics
@@ -0,0 +1,11 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+SUMMARY:rrule monthly with end
+DTSTART;VALUE=DATE-TIME:20030919T090000
+DTEND;VALUE=DATE-TIME:20030919T113000
+RRULE:FREQ=MONTHLY;UNTIL=20050819;
+END:VEVENT
+END:VCALENDAR
+
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-weekly.diary-american b/test/lisp/calendar/icalendar-resources/import-rrule-weekly.diary-american
new file mode 100644
index 00000000000..d8bf2eba104
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-weekly.diary-american
@@ -0,0 +1 @@
+&%%(and (diary-cyclic 7 9 19 2003)) 09:00-11:30 rrule weekly
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-weekly.diary-european b/test/lisp/calendar/icalendar-resources/import-rrule-weekly.diary-european
new file mode 100644
index 00000000000..e368fde9709
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-weekly.diary-european
@@ -0,0 +1 @@
+&%%(and (diary-cyclic 7 19 9 2003)) 09:00-11:30 rrule weekly
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-weekly.diary-iso b/test/lisp/calendar/icalendar-resources/import-rrule-weekly.diary-iso
new file mode 100644
index 00000000000..49cd9d8ace6
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-weekly.diary-iso
@@ -0,0 +1 @@
+&%%(and (diary-cyclic 7 2003 9 19)) 09:00-11:30 rrule weekly
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-weekly.ics b/test/lisp/calendar/icalendar-resources/import-rrule-weekly.ics
new file mode 100644
index 00000000000..c3f0b8ae933
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-weekly.ics
@@ -0,0 +1,11 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+SUMMARY:rrule weekly
+DTSTART;VALUE=DATE-TIME:20030919T090000
+DTEND;VALUE=DATE-TIME:20030919T113000
+RRULE:FREQ=WEEKLY;
+END:VEVENT
+END:VCALENDAR
+
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-american b/test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-american
new file mode 100644
index 00000000000..bc485d8a6c4
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-american
@@ -0,0 +1 @@
+&%%(diary-anniversary 9 19 2002) 09:00-11:30 rrule yearly
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-european b/test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-european
new file mode 100644
index 00000000000..42509d42bc8
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-european
@@ -0,0 +1 @@
+&%%(diary-anniversary 19 9 2002) 09:00-11:30 rrule yearly
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-iso b/test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-iso
new file mode 100644
index 00000000000..72fe6e12cbd
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-iso
@@ -0,0 +1 @@
+&%%(diary-anniversary 2002 9 19) 09:00-11:30 rrule yearly
diff --git a/test/lisp/calendar/icalendar-resources/import-rrule-yearly.ics b/test/lisp/calendar/icalendar-resources/import-rrule-yearly.ics
new file mode 100644
index 00000000000..21cca097f7e
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-rrule-yearly.ics
@@ -0,0 +1,11 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+SUMMARY:rrule yearly
+DTSTART;VALUE=DATE-TIME:20030919T090000
+DTEND;VALUE=DATE-TIME:20030919T113000
+RRULE:FREQ=YEARLY;INTERVAL=2
+END:VEVENT
+END:VCALENDAR
+
diff --git a/test/lisp/calendar/icalendar-resources/import-with-timezone.diary-iso b/test/lisp/calendar/icalendar-resources/import-with-timezone.diary-iso
new file mode 100644
index 00000000000..f99b59213e5
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-with-timezone.diary-iso
@@ -0,0 +1,2 @@
+&2012/1/15 15:00-15:30 standardtime
+&2012/12/15 11:00-11:30 daylightsavingtime
diff --git a/test/lisp/calendar/icalendar-resources/import-with-timezone.ics b/test/lisp/calendar/icalendar-resources/import-with-timezone.ics
new file mode 100644
index 00000000000..110a9835e41
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-with-timezone.ics
@@ -0,0 +1,27 @@
+BEGIN:VCALENDAR
+BEGIN:VTIMEZONE
+TZID:fictional, nonexistent, arbitrary
+BEGIN:STANDARD
+DTSTART:20100101T000000
+TZOFFSETFROM:+0200
+TZOFFSETTO:-0200
+RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=01
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:20101201T000000
+TZOFFSETFROM:-0200
+TZOFFSETTO:+0200
+RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=11
+END:DAYLIGHT
+END:VTIMEZONE
+BEGIN:VEVENT
+SUMMARY:standardtime
+DTSTART;TZID="fictional, nonexistent, arbitrary":20120115T120000
+DTEND;TZID="fictional, nonexistent, arbitrary":20120115T123000
+END:VEVENT
+BEGIN:VEVENT
+SUMMARY:daylightsavingtime
+DTSTART;TZID="fictional, nonexistent, arbitrary":20121215T120000
+DTEND;TZID="fictional, nonexistent, arbitrary":20121215T123000
+END:VEVENT
+END:VCALENDAR
diff --git a/test/lisp/calendar/icalendar-resources/import-with-uid.diary-american b/test/lisp/calendar/icalendar-resources/import-with-uid.diary-american
new file mode 100644
index 00000000000..9b2f06afc26
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-with-uid.diary-american
@@ -0,0 +1,2 @@
+&9/19/2003 09:00-11:30 non-recurring
+ UID: 1234567890uid
diff --git a/test/lisp/calendar/icalendar-resources/import-with-uid.diary-european b/test/lisp/calendar/icalendar-resources/import-with-uid.diary-european
new file mode 100644
index 00000000000..95db4d40151
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-with-uid.diary-european
@@ -0,0 +1,2 @@
+&19/9/2003 09:00-11:30 non-recurring
+ UID: 1234567890uid
diff --git a/test/lisp/calendar/icalendar-resources/import-with-uid.diary-iso b/test/lisp/calendar/icalendar-resources/import-with-uid.diary-iso
new file mode 100644
index 00000000000..d372e5a3d1f
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-with-uid.diary-iso
@@ -0,0 +1,2 @@
+&2003/9/19 09:00-11:30 non-recurring
+ UID: 1234567890uid
diff --git a/test/lisp/calendar/icalendar-resources/import-with-uid.ics b/test/lisp/calendar/icalendar-resources/import-with-uid.ics
new file mode 100644
index 00000000000..db412d9d9f5
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/import-with-uid.ics
@@ -0,0 +1,10 @@
+BEGIN:VCALENDAR
+PRODID:-//Emacs//NONSGML icalendar.el//EN
+VERSION:2.0
+BEGIN:VEVENT
+UID:1234567890uid
+SUMMARY:non-recurring
+DTSTART;VALUE=DATE-TIME:20030919T090000
+DTEND;VALUE=DATE-TIME:20030919T113000
+END:VEVENT
+END:VCALENDAR
diff --git a/test/lisp/calendar/icalendar-tests.el b/test/lisp/calendar/icalendar-tests.el
index 80a79db75cf..7f8cd479146 100644
--- a/test/lisp/calendar/icalendar-tests.el
+++ b/test/lisp/calendar/icalendar-tests.el
@@ -1,6 +1,6 @@
-;; icalendar-tests.el --- Test suite for icalendar.el
+;;; icalendar-tests.el --- Test suite for icalendar.el -*- lexical-binding:t -*-
-;; Copyright (C) 2005, 2008-2017 Free Software Foundation, Inc.
+;; Copyright (C) 2005, 2008-2022 Free Software Foundation, Inc.
;; Author: Ulf Jasper <ulf.jasper@web.de>
;; Created: March 2005
@@ -32,6 +32,7 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'icalendar)
;; ======================================================================
@@ -51,23 +52,31 @@
(replace-regexp-in-string "[ \t\n]+\\'" ""
(replace-regexp-in-string "\\`[ \t\n]+" "" string)))
+(defun icalendar-tests--get-file-contents (filename)
+ "Return contents of file in test data directory named FILENAME."
+ (with-temp-buffer
+ (let ((coding-system-for-read 'raw-text)
+ (inhibit-eol-conversion t))
+ (insert-file-contents-literally
+ (ert-resource-file filename))
+ (buffer-string))))
+
;; ======================================================================
;; Tests of functions
;; ======================================================================
(ert-deftest icalendar--create-uid ()
"Test for `icalendar--create-uid'."
- (let* ((icalendar-uid-format "xxx-%t-%c-%h-%u-%s")
+ (let* ((icalendar-uid-format "xxx-%c-%h-%u-%s")
(icalendar--uid-count 77)
(entry-full "30.06.1964 07:01 blahblah")
(hash (format "%d" (abs (sxhash entry-full))))
(contents "DTSTART:19640630T070100\nblahblah")
(username (or user-login-name "UNKNOWN_USER")))
- (cl-letf (((symbol-function 'current-time) (lambda () '(1 2 3))))
- (should (= 77 icalendar--uid-count))
- (should (string= (concat "xxx-123-77-" hash "-" username "-19640630")
- (icalendar--create-uid entry-full contents)))
- (should (= 78 icalendar--uid-count)))
+ (should (= 77 icalendar--uid-count))
+ (should (string= (concat "xxx-77-" hash "-" username "-19640630")
+ (icalendar--create-uid entry-full contents)))
+ (should (= 78 icalendar--uid-count))
(setq contents "blahblah")
(setq icalendar-uid-format "yyy%syyy")
(should (string= (concat "yyyDTSTARTyyy")
@@ -78,7 +87,7 @@
(let* ((calendar-date-style 'iso)
result)
(setq result (icalendar--convert-anniversary-to-ical
- "" "%%(diary-anniversary 1964 6 30) g"))
+ "" "%%(diary-anniversary 1963 6 30) g"))
(should (consp result))
(should (string= (concat
"\nDTSTART;VALUE=DATE:19640630"
@@ -184,6 +193,7 @@
(ert-deftest icalendar--parse-vtimezone ()
"Test method for `icalendar--parse-vtimezone'."
(let (vtimezone result)
+ ;; testcase: valid timezone with rrule
(setq vtimezone (icalendar-tests--get-ical-event "BEGIN:VTIMEZONE
TZID:thename
BEGIN:STANDARD
@@ -205,6 +215,8 @@ END:VTIMEZONE
(message (cdr result))
(should (string= "STD-02:00DST-03:00,M3.5.0/03:00:00,M10.5.0/04:00:00"
(cdr result)))
+
+ ;; testcase: name of tz contains comma
(setq vtimezone (icalendar-tests--get-ical-event "BEGIN:VTIMEZONE
TZID:anothername, with a comma
BEGIN:STANDARD
@@ -226,7 +238,8 @@ END:VTIMEZONE
(message (cdr result))
(should (string= "STD-02:00DST-03:00,M3.2.1/03:00:00,M10.2.1/04:00:00"
(cdr result)))
- ;; offsetfrom = offsetto
+
+ ;; testcase: offsetfrom = offsetto
(setq vtimezone (icalendar-tests--get-ical-event "BEGIN:VTIMEZONE
TZID:Kolkata, Chennai, Mumbai, New Delhi
X-MICROSOFT-CDO-TZID:23
@@ -246,7 +259,10 @@ END:VTIMEZONE
(should (string= "Kolkata, Chennai, Mumbai, New Delhi" (car result)))
(message (cdr result))
(should (string= "STD-05:30DST-05:30,M1.1.1/00:00:00,M1.1.1/00:00:00"
- (cdr result)))))
+ (cdr result)))
+
+ ;; FIXME: add testcase that covers changes for fix of bug#34315
+ ))
(ert-deftest icalendar--convert-ordinary-to-ical ()
"Test method for `icalendar--convert-ordinary-to-ical'."
@@ -337,7 +353,7 @@ END:VTIMEZONE
(let ((calendar-date-style 'iso))
;; numeric iso
(should (string= "20080511"
- (icalendar--datestring-to-isodate "2008 05 11")))
+ (icalendar--datestring-to-isodate "2008 05 11")))
(should (string= "20080531"
(icalendar--datestring-to-isodate "2008 05 31")))
(should (string= "20080602"
@@ -368,7 +384,19 @@ END:VTIMEZONE
(should (string= "20081105"
(icalendar--datestring-to-isodate "05 Nov 2008")))
(should (string= "20081105"
- (icalendar--datestring-to-isodate "2008 Nov 05")))))
+ (icalendar--datestring-to-isodate "2008 Nov 05")))
+
+ ;; non-numeric with day-shift and year-shift
+ (setq calendar-date-style nil) ;not necessary for conversion
+ (should (string= "20210212"
+ (icalendar--datestring-to-isodate "2021 Feb 11" 1)))
+ (should (string= "20210131"
+ (icalendar--datestring-to-isodate "2021 Feb 11" -11)))
+ (should (string= "20200211"
+ (icalendar--datestring-to-isodate "2021 Feb 11" nil -1)))
+ (should (string= "21010211"
+ (icalendar--datestring-to-isodate "2021 Feb 11" nil 80)))
+ ))
(ert-deftest icalendar--first-weekday-of-year ()
"Test method for `icalendar-first-weekday-of-year'."
@@ -420,11 +448,11 @@ END:VEVENT
")))
(should (string= "SUM sum DES des LOC loc ORG org"
(icalendar--format-ical-event event)))
- (setq icalendar-import-format (lambda (&rest ignore)
+ (setq icalendar-import-format (lambda (&rest _ignore)
"helloworld"))
(should (string= "helloworld" (icalendar--format-ical-event event)))
(setq icalendar-import-format
- (lambda (e)
+ (lambda (event)
(format "-%s-%s-%s-%s-%s-%s-%s-"
(icalendar--get-event-property event 'SUMMARY)
(icalendar--get-event-property event 'DESCRIPTION)
@@ -466,8 +494,7 @@ END:VEVENT
(ert-deftest icalendar--decode-isodatetime ()
"Test `icalendar--decode-isodatetime'."
- (let ((tz (getenv "TZ"))
- result)
+ (let ((tz (getenv "TZ")))
(unwind-protect
(progn
;; Use Eastern European Time (UTC+2, UTC+3 daylight saving)
@@ -484,17 +511,132 @@ END:VEVENT
(should (equal '(0 0 10 1 8 2013 4 t 10800)
(icalendar--decode-isodatetime "20130801T100000")))
+ ;; testcase: no time zone in input, shift by -1 days
+ ;; 1 Jan 2013 10:00 -> 31 Dec 2012
+ (should (equal '(0 0 10 31 12 2012 1 nil 7200)
+ (icalendar--decode-isodatetime "20130101T100000" -1)))
+ ;; 1 Aug 2013 10:00 (DST) -> 31 Jul 2012 (DST)
+ (should (equal '(0 0 10 31 7 2013 3 t 10800)
+ (icalendar--decode-isodatetime "20130801T100000" -1)))
+
+
;; testcase: UTC time zone specifier in input -> convert to local time
- ;; 31 Dec 2013 23:00 UTC -> 1 Jan 2013 01:00 EET
+ ;; 31 Dec 2013 23:00 UTC -> 1 Jan 2014 01:00 EET
(should (equal '(0 0 1 1 1 2014 3 nil 7200)
(icalendar--decode-isodatetime "20131231T230000Z")))
;; 1 Aug 2013 10:00 UTC -> 1 Aug 2013 13:00 EEST
(should (equal '(0 0 13 1 8 2013 4 t 10800)
(icalendar--decode-isodatetime "20130801T100000Z")))
+ ;; testcase: override timezone with Central European Time, 1 Jan 2013 10:00 -> 1 Jan 2013 11:00
+ (should (equal '(0 0 11 1 1 2013 2 nil 7200)
+ (icalendar--decode-isodatetime "20130101T100000" nil
+ '(3600 "CET"))))
+ ;; testcase: override timezone (UTC-02:00), 1 Jan 2013 10:00 -> 1 Jan 2013 14:00
+ (should (equal '(0 0 14 1 1 2013 2 nil 7200)
+ (icalendar--decode-isodatetime "20130101T100000" nil -7200)))
+
+ ;; FIXME: add testcase that covers changes for fix of bug#34315
+
+ )
+ ;; restore time-zone even if something went terribly wrong
+ (setenv "TZ" tz))))
+
+(ert-deftest icalendar--convert-tz-offset ()
+ "Test `icalendar--convert-tz-offset'."
+ (let ((tz (getenv "TZ")))
+ (unwind-protect
+ (progn
+ ;; Use Eastern European Time (UTC+2, UTC+3 daylight saving)
+ (setenv "TZ" "EET-2EEST,M3.5.0/3,M10.5.0/4")
+
+ ;; testcase: artificial input
+ (should (equal '("DST-03:00" . "M5.1.1/01:23:45")
+ (icalendar--convert-tz-offset
+ '((DTSTART nil "________T012345") ;
+ (TZOFFSETFROM nil "+0200")
+ (TZOFFSETTO nil "+0300")
+ (RRULE nil "FREQ=YEARLY;INTERVAL=1;BYDAY=1MO;BYMONTH=5"))
+ t)))
+
+ ;; testcase: Europe/Berlin Standard
+ (should (equal '("STD-01:00" . "M10.5.0/03:00:00")
+ (icalendar--convert-tz-offset
+ '((TZOFFSETFROM nil "+0200")
+ (TZOFFSETTO nil "+0100")
+ (TZNAME nil CET)
+ (DTSTART nil "19701025T030000")
+ (RRULE nil "FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU"))
+ nil)))
+
+ ;; testcase: Europe/Berlin DST
+ (should (equal '("DST-02:00" . "M3.5.0/02:00:00")
+ (icalendar--convert-tz-offset
+ '((TZOFFSETFROM nil "+0100")
+ (TZOFFSETTO nil "+0200")
+ (TZNAME nil CEST)
+ (DTSTART nil "19700329T020000")
+ (RRULE nil "FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU"))
+ t)))
+
+ ;; testcase: dtstart is mandatory
+ (should (null (icalendar--convert-tz-offset
+ '((TZOFFSETFROM nil "+0100")
+ (TZOFFSETTO nil "+0200")
+ (RRULE nil "FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU"))
+ t)))
+
+ ;; FIXME: rrule and rdate are NOT mandatory! Must fix code
+ ;; before activating these testcases
+ ;; ;; testcase: no rrule and no rdate => no result
+ ;; (should (null (icalendar--convert-tz-offset
+ ;; '((TZOFFSETFROM nil "+0100")
+ ;; (TZOFFSETTO nil "+0200")
+ ;; (DTSTART nil "19700329T020000"))
+ ;; t)))
+ ;; ;; testcase: no rrule with rdate => no result
+ ;; (should (null (icalendar--convert-tz-offset
+ ;; '((TZOFFSETFROM nil "+0100")
+ ;; (TZOFFSETTO nil "+0200")
+ ;; (DTSTART nil "18840101T000000")
+ ;; (RDATE nil "18840101T000000"))
+ ;; t)))
)
;; restore time-zone even if something went terribly wrong
- (setenv "TZ" tz))) )
+ (setenv "TZ" tz))))
+
+(ert-deftest icalendar--decode-isoduration ()
+ "Test `icalendar--decode-isoduration'."
+
+ ;; testcase: 7 days
+ (should (equal '(0 0 0 7 0 0)
+ (icalendar--decode-isoduration "P7D")))
+
+ ;; testcase: 7 days, one second -- see bug#34315
+ (should (equal '(1 0 0 7 0 0)
+ (icalendar--decode-isoduration "P7DT1S")))
+
+ ;; testcase: 3 hours, 2 minutes, one second
+ (should (equal '(1 2 3 0 0 0)
+ (icalendar--decode-isoduration "PT3H2M1S")))
+
+ ;; testcase: 99 days, 3 hours, 2 minutes, one second -- see bug#34315
+ (should (equal '(1 2 3 99 0 0)
+ (icalendar--decode-isoduration "P99DT3H2M1S")))
+
+ ;; testcase: 2 weeks
+ (should (equal '(0 0 0 14 0 0)
+ (icalendar--decode-isoduration "P2W")))
+
+ ;; testcase: rfc2445, section 4.3.6: 15 days, 5 hours and 20 seconds -- see bug#34315
+ (should (equal '(20 0 5 15 0 0)
+ (icalendar--decode-isoduration "P15DT5H0M20S")))
+
+ ;; testcase: rfc2445, section 4.3.6: 7 weeks
+ (should (equal '(0 0 0 49 0 0)
+ (icalendar--decode-isoduration "P7W")))
+ )
+
;; ======================================================================
;; Export tests
@@ -509,8 +651,8 @@ Argument INPUT-AMERICAN american style diary string.
Argument EXPECTED-OUTPUT expected iCalendar result string.
Optional argument ALARMS the value of `icalendar-export-alarms' for this test.
-European style input data must use german month names. American
-and ISO style input data must use english month names."
+European style input data must use German month names. American
+and ISO style input data must use English month names."
(let ((tz (getenv "TZ"))
(calendar-date-style 'iso)
(icalendar-recurring-start-year 2000)
@@ -556,17 +698,18 @@ and ISO style input data must use english month names."
"Actually perform export test.
Argument INPUT input diary string.
Argument EXPECTED-OUTPUT expected iCalendar result string."
- (let ((temp-file (make-temp-file "icalendar-tests-ics")))
+ (ert-with-temp-file temp-file
+ :suffix "icalendar-tests-ics"
(unwind-protect
- (progn
- (with-temp-buffer
- (insert input)
- (icalendar-export-region (point-min) (point-max) temp-file))
- (save-excursion
- (find-file temp-file)
- (goto-char (point-min))
- (cond (expected-output
- (should (re-search-forward "^\\s-*BEGIN:VCALENDAR
+ (progn
+ (with-temp-buffer
+ (insert input)
+ (icalendar-export-region (point-min) (point-max) temp-file))
+ (save-excursion
+ (find-file temp-file)
+ (goto-char (point-min))
+ (cond (expected-output
+ (should (re-search-forward "^\\s-*BEGIN:VCALENDAR
PRODID:-//Emacs//NONSGML icalendar.el//EN
VERSION:2.0
BEGIN:VEVENT
@@ -575,23 +718,22 @@ UID:emacs[0-9]+
END:VEVENT
END:VCALENDAR
\\s-*$"
- nil t))
- (should (string-match
- (concat "^\\s-*"
- (regexp-quote (buffer-substring-no-properties
- (match-beginning 1) (match-end 1)))
- "\\s-*$")
- expected-output)))
- (t
- (should (re-search-forward "^\\s-*BEGIN:VCALENDAR
+ nil t))
+ (should (string-match
+ (concat "^\\s-*"
+ (regexp-quote (buffer-substring-no-properties
+ (match-beginning 1) (match-end 1)))
+ "\\s-*$")
+ expected-output)))
+ (t
+ (should (re-search-forward "^\\s-*BEGIN:VCALENDAR
PRODID:-//Emacs//NONSGML icalendar.el//EN
VERSION:2.0
END:VCALENDAR
\\s-*$"
- nil t))))))
+ nil t))))))
;; cleanup!!
- (kill-buffer (find-buffer-visiting temp-file))
- (delete-file temp-file))))
+ (kill-buffer (find-buffer-visiting temp-file)))))
(ert-deftest icalendar-export-ordinary-no-time ()
"Perform export test."
@@ -700,18 +842,18 @@ SUMMARY:yearly no time
"Perform export test."
;; anniversaries
(icalendar-tests--test-export
- "%%(diary-anniversary 1989 10 3) anniversary no time"
- "%%(diary-anniversary 3 10 1989) anniversary no time"
- "%%(diary-anniversary 10 3 1989) anniversary no time"
+ "%%(diary-anniversary 1988 10 3) anniversary no time"
+ "%%(diary-anniversary 3 10 1988) anniversary no time"
+ "%%(diary-anniversary 10 3 1988) anniversary no time"
"DTSTART;VALUE=DATE:19891003
DTEND;VALUE=DATE:19891004
RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=10;BYMONTHDAY=03
SUMMARY:anniversary no time
")
(icalendar-tests--test-export
- "%%(diary-anniversary 1989 10 3) 19:00-20:00 anniversary with time"
- "%%(diary-anniversary 3 10 1989) 19:00-20:00 anniversary with time"
- "%%(diary-anniversary 10 3 1989) 19:00-20:00 anniversary with time"
+ "%%(diary-anniversary 1988 10 3) 19:00-20:00 anniversary with time"
+ "%%(diary-anniversary 3 10 1988) 19:00-20:00 anniversary with time"
+ "%%(diary-anniversary 10 3 1988) 19:00-20:00 anniversary with time"
"DTSTART;VALUE=DATE-TIME:19891003T190000
DTEND;VALUE=DATE-TIME:19891004T200000
RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=10;BYMONTHDAY=03
@@ -761,12 +903,12 @@ SUMMARY:no alarm
"
nil)
- ;; 10 minutes in advance, audio
- (icalendar-tests--test-export
- "2014 Nov 17 19:30 audio alarm"
- "17 Nov 2014 19:30 audio alarm"
- "Nov 17 2014 19:30 audio alarm"
- "DTSTART;VALUE=DATE-TIME:20141117T193000
+ ;; 10 minutes in advance, audio
+ (icalendar-tests--test-export
+ "2014 Nov 17 19:30 audio alarm"
+ "17 Nov 2014 19:30 audio alarm"
+ "Nov 17 2014 19:30 audio alarm"
+ "DTSTART;VALUE=DATE-TIME:20141117T193000
DTEND;VALUE=DATE-TIME:20141117T203000
SUMMARY:audio alarm
BEGIN:VALARM
@@ -774,14 +916,14 @@ ACTION:AUDIO
TRIGGER:-PT10M
END:VALARM
"
- '(10 ((audio))))
+ '(10 ((audio))))
- ;; 20 minutes in advance, display
- (icalendar-tests--test-export
- "2014 Nov 17 19:30 display alarm"
- "17 Nov 2014 19:30 display alarm"
- "Nov 17 2014 19:30 display alarm"
- "DTSTART;VALUE=DATE-TIME:20141117T193000
+ ;; 20 minutes in advance, display
+ (icalendar-tests--test-export
+ "2014 Nov 17 19:30 display alarm"
+ "17 Nov 2014 19:30 display alarm"
+ "Nov 17 2014 19:30 display alarm"
+ "DTSTART;VALUE=DATE-TIME:20141117T193000
DTEND;VALUE=DATE-TIME:20141117T203000
SUMMARY:display alarm
BEGIN:VALARM
@@ -790,14 +932,14 @@ TRIGGER:-PT20M
DESCRIPTION:display alarm
END:VALARM
"
- '(20 ((display))))
+ '(20 ((display))))
- ;; 66 minutes in advance, email
- (icalendar-tests--test-export
- "2014 Nov 17 19:30 email alarm"
- "17 Nov 2014 19:30 email alarm"
- "Nov 17 2014 19:30 email alarm"
- "DTSTART;VALUE=DATE-TIME:20141117T193000
+ ;; 66 minutes in advance, email
+ (icalendar-tests--test-export
+ "2014 Nov 17 19:30 email alarm"
+ "17 Nov 2014 19:30 email alarm"
+ "Nov 17 2014 19:30 email alarm"
+ "DTSTART;VALUE=DATE-TIME:20141117T193000
DTEND;VALUE=DATE-TIME:20141117T203000
SUMMARY:email alarm
BEGIN:VALARM
@@ -809,14 +951,14 @@ ATTENDEE:MAILTO:att.one@email.com
ATTENDEE:MAILTO:att.two@email.com
END:VALARM
"
- '(66 ((email ("att.one@email.com" "att.two@email.com")))))
+ '(66 ((email ("att.one@email.com" "att.two@email.com")))))
- ;; 2 minutes in advance, all alarms
- (icalendar-tests--test-export
- "2014 Nov 17 19:30 all alarms"
- "17 Nov 2014 19:30 all alarms"
- "Nov 17 2014 19:30 all alarms"
- "DTSTART;VALUE=DATE-TIME:20141117T193000
+ ;; 2 minutes in advance, all alarms
+ (icalendar-tests--test-export
+ "2014 Nov 17 19:30 all alarms"
+ "17 Nov 2014 19:30 all alarms"
+ "Nov 17 2014 19:30 all alarms"
+ "DTSTART;VALUE=DATE-TIME:20141117T193000
DTEND;VALUE=DATE-TIME:20141117T203000
SUMMARY:all alarms
BEGIN:VALARM
@@ -837,19 +979,22 @@ TRIGGER:-PT2M
DESCRIPTION:all alarms
END:VALARM
"
- '(2 ((email ("att.one@email.com" "att.two@email.com")) (audio) (display)))))
+ '(2 ((email ("att.one@email.com" "att.two@email.com")) (audio) (display)))))
;; ======================================================================
;; Import tests
;; ======================================================================
-(defun icalendar-tests--test-import (input expected-iso expected-european
- expected-american)
+(defun icalendar-tests--test-import (filename expected-iso expected-european
+ expected-american)
"Perform import test.
-Argument INPUT icalendar event string.
-Argument EXPECTED-ISO expected iso style diary string.
-Argument EXPECTED-EUROPEAN expected european style diary string.
-Argument EXPECTED-AMERICAN expected american style diary string.
+Argument FILENAME ics file to import.
+Argument EXPECTED-ISO diary-file containing expected
+iso-calendar-style result.
+Argument EXPECTED-EUROPEAN diary-file containing expected
+european-calendar-style result.
+Argument EXPECTED-AMERICAN diary-file containing expected
+american-calendar-style result.
During import test the timezone is set to Central European Time."
(let ((timezone (getenv "TZ")))
(unwind-protect
@@ -858,14 +1003,7 @@ During import test the timezone is set to Central European Time."
;; Eg hydra.nixos.org.
(setenv "TZ" "CET-1CEST,M3.5.0/2,M10.5.0/3")
(with-temp-buffer
- (if (string-match "^BEGIN:VCALENDAR" input)
- (insert input)
- (insert "BEGIN:VCALENDAR\nPRODID:-//Emacs//NONSGML icalendar.el//EN\n")
- (insert "VERSION:2.0\nBEGIN:VEVENT\n")
- (insert input)
- (unless (eq (char-before) ?\n)
- (insert "\n"))
- (insert "END:VEVENT\nEND:VCALENDAR\n"))
+ (insert (icalendar-tests--get-file-contents filename))
(let ((icalendar-import-format "%s%d%l%o%t%u%c%U")
(icalendar-import-format-summary "%s")
(icalendar-import-format-location "\n Location: %s")
@@ -878,26 +1016,30 @@ During import test the timezone is set to Central European Time."
calendar-date-style)
(when expected-iso
(setq calendar-date-style 'iso)
- (icalendar-tests--do-test-import input expected-iso))
+ (icalendar-tests--do-test-import
+ (icalendar-tests--get-file-contents expected-iso)))
(when expected-european
(setq calendar-date-style 'european)
- (icalendar-tests--do-test-import input expected-european))
+ (icalendar-tests--do-test-import
+ (icalendar-tests--get-file-contents expected-european)))
(when expected-american
(setq calendar-date-style 'american)
- (icalendar-tests--do-test-import input expected-american)))))
+ (icalendar-tests--do-test-import
+ (icalendar-tests--get-file-contents expected-american))))))
(setenv "TZ" timezone))))
-(defun icalendar-tests--do-test-import (input expected-output)
+(defun icalendar-tests--do-test-import (expected-output)
"Actually perform import test.
-Argument INPUT input icalendar string.
-Argument EXPECTED-OUTPUT expected diary string."
- (let ((temp-file (make-temp-file "icalendar-test-diary")))
+Argument EXPECTED-OUTPUT file containing expected diary string."
+ (ert-with-temp-file temp-file
+ :suffix "icalendar-test-diary"
;; Test the Catch-the-mysterious-coding-header logic below.
;; Ruby-mode adds an after-save-hook which inserts the header!
;; (save-excursion
;; (find-file temp-file)
;; (ruby-mode))
- (icalendar-import-buffer temp-file t t)
+ (let ((coding-system-for-write 'raw-text))
+ (icalendar-import-buffer temp-file t t))
(save-excursion
(find-file temp-file)
;; Check for the mysterious "# coding: ..." header, remove it
@@ -920,439 +1062,139 @@ Argument EXPECTED-OUTPUT expected diary string."
(let ((result (buffer-substring-no-properties (point-min) (point-max))))
(should (string= expected-output result)))
- (kill-buffer (find-buffer-visiting temp-file))
- (delete-file temp-file))))
+ (kill-buffer (find-buffer-visiting temp-file)))))
(ert-deftest icalendar-import-non-recurring ()
"Perform standard import tests."
- (icalendar-tests--test-import
- "SUMMARY:non-recurring
-DTSTART;VALUE=DATE-TIME:20030919T090000
-DTEND;VALUE=DATE-TIME:20030919T113000"
- "&2003/9/19 09:00-11:30 non-recurring\n"
- "&19/9/2003 09:00-11:30 non-recurring\n"
- "&9/19/2003 09:00-11:30 non-recurring\n")
- (icalendar-tests--test-import
- "SUMMARY:non-recurring allday
-DTSTART;VALUE=DATE-TIME:20030919"
- "&2003/9/19 non-recurring allday\n"
- "&19/9/2003 non-recurring allday\n"
- "&9/19/2003 non-recurring allday\n")
- (icalendar-tests--test-import
- ;; Checkdoc removes trailing blanks. Therefore: format!
- (format "%s\n%s\n%s" "SUMMARY:long " " summary"
- "DTSTART;VALUE=DATE:20030919")
- "&2003/9/19 long summary\n"
- "&19/9/2003 long summary\n"
- "&9/19/2003 long summary\n")
- (icalendar-tests--test-import
- "UID:748f2da0-0d9b-11d8-97af-b4ec8686ea61
-SUMMARY:Sommerferien
-STATUS:TENTATIVE
-CLASS:PRIVATE
-X-MOZILLA-ALARM-DEFAULT-UNITS:Minuten
-X-MOZILLA-RECUR-DEFAULT-INTERVAL:0
-DTSTART;VALUE=DATE:20040719
-DTEND;VALUE=DATE:20040828
-DTSTAMP:20031103T011641Z
-"
- "&%%(and (diary-block 2004 7 19 2004 8 27)) Sommerferien
- Status: TENTATIVE
- Class: PRIVATE
- UID: 748f2da0-0d9b-11d8-97af-b4ec8686ea61
-"
- "&%%(and (diary-block 19 7 2004 27 8 2004)) Sommerferien
- Status: TENTATIVE
- Class: PRIVATE
- UID: 748f2da0-0d9b-11d8-97af-b4ec8686ea61
-"
- "&%%(and (diary-block 7 19 2004 8 27 2004)) Sommerferien
- Status: TENTATIVE
- Class: PRIVATE
- UID: 748f2da0-0d9b-11d8-97af-b4ec8686ea61
-")
- (icalendar-tests--test-import
- "UID
- :04979712-3902-11d9-93dd-8f9f4afe08da
-SUMMARY
- :folded summary
-STATUS
- :TENTATIVE
-CLASS
- :PRIVATE
-X-MOZILLA-ALARM-DEFAULT-LENGTH
- :0
-DTSTART
- :20041123T140000
-DTEND
- :20041123T143000
-DTSTAMP
- :20041118T013430Z
-LAST-MODIFIED
- :20041118T013640Z
-"
- "&2004/11/23 14:00-14:30 folded summary
- Status: TENTATIVE
- Class: PRIVATE
- UID: 04979712-3902-11d9-93dd-8f9f4afe08da\n"
- "&23/11/2004 14:00-14:30 folded summary
- Status: TENTATIVE
- Class: PRIVATE
- UID: 04979712-3902-11d9-93dd-8f9f4afe08da\n"
- "&11/23/2004 14:00-14:30 folded summary
- Status: TENTATIVE
- Class: PRIVATE
- UID: 04979712-3902-11d9-93dd-8f9f4afe08da\n")
-
- (icalendar-tests--test-import
- "UID
- :6161a312-3902-11d9-b512-f764153bb28b
-SUMMARY
- :another example
-STATUS
- :TENTATIVE
-CLASS
- :PRIVATE
-X-MOZILLA-ALARM-DEFAULT-LENGTH
- :0
-DTSTART
- :20041123T144500
-DTEND
- :20041123T154500
-DTSTAMP
- :20041118T013641Z
-"
- "&2004/11/23 14:45-15:45 another example
- Status: TENTATIVE
- Class: PRIVATE
- UID: 6161a312-3902-11d9-b512-f764153bb28b\n"
- "&23/11/2004 14:45-15:45 another example
- Status: TENTATIVE
- Class: PRIVATE
- UID: 6161a312-3902-11d9-b512-f764153bb28b\n"
- "&11/23/2004 14:45-15:45 another example
- Status: TENTATIVE
- Class: PRIVATE
- UID: 6161a312-3902-11d9-b512-f764153bb28b\n"))
+ (icalendar-tests--test-import "import-non-recurring-1.ics"
+ "import-non-recurring-1.diary-iso"
+ "import-non-recurring-1.diary-european"
+ "import-non-recurring-1.diary-american")
+ (icalendar-tests--test-import "import-non-recurring-all-day.ics"
+ "import-non-recurring-all-day.diary-iso"
+ "import-non-recurring-all-day.diary-european"
+ "import-non-recurring-all-day.diary-american")
+ (icalendar-tests--test-import "import-non-recurring-long-summary.ics"
+ "import-non-recurring-long-summary.diary-iso"
+ "import-non-recurring-long-summary.diary-european"
+ "import-non-recurring-long-summary.diary-american")
+ (icalendar-tests--test-import "import-non-recurring-block.ics"
+ "import-non-recurring-block.diary-iso"
+ "import-non-recurring-block.diary-european"
+ "import-non-recurring-block.diary-american")
+ (icalendar-tests--test-import "import-non-recurring-folded-summary.ics"
+ "import-non-recurring-folded-summary.diary-iso"
+ "import-non-recurring-folded-summary.diary-european"
+ "import-non-recurring-folded-summary.diary-american")
+ (icalendar-tests--test-import "import-non-recurring-another-example.ics"
+ "import-non-recurring-another-example.diary-iso"
+ "import-non-recurring-another-example.diary-european"
+ "import-non-recurring-another-example.diary-american"))
+
(ert-deftest icalendar-import-rrule ()
- (icalendar-tests--test-import
- "SUMMARY:rrule daily
-DTSTART;VALUE=DATE-TIME:20030919T090000
-DTEND;VALUE=DATE-TIME:20030919T113000
-RRULE:FREQ=DAILY;
-"
- "&%%(and (diary-cyclic 1 2003 9 19)) 09:00-11:30 rrule daily\n"
- "&%%(and (diary-cyclic 1 19 9 2003)) 09:00-11:30 rrule daily\n"
- "&%%(and (diary-cyclic 1 9 19 2003)) 09:00-11:30 rrule daily\n")
- ;; RRULE examples
- (icalendar-tests--test-import
- "SUMMARY:rrule daily
-DTSTART;VALUE=DATE-TIME:20030919T090000
-DTEND;VALUE=DATE-TIME:20030919T113000
-RRULE:FREQ=DAILY;INTERVAL=2
-"
- "&%%(and (diary-cyclic 2 2003 9 19)) 09:00-11:30 rrule daily\n"
- "&%%(and (diary-cyclic 2 19 9 2003)) 09:00-11:30 rrule daily\n"
- "&%%(and (diary-cyclic 2 9 19 2003)) 09:00-11:30 rrule daily\n")
- (icalendar-tests--test-import
- "SUMMARY:rrule daily with exceptions
-DTSTART;VALUE=DATE-TIME:20030919T090000
-DTEND;VALUE=DATE-TIME:20030919T113000
-RRULE:FREQ=DAILY;INTERVAL=2
-EXDATE:20030921,20030925
-"
- "&%%(and (not (diary-date 2003 9 25)) (not (diary-date 2003 9 21)) (diary-cyclic 2 2003 9 19)) 09:00-11:30 rrule daily with exceptions\n"
- "&%%(and (not (diary-date 25 9 2003)) (not (diary-date 21 9 2003)) (diary-cyclic 2 19 9 2003)) 09:00-11:30 rrule daily with exceptions\n"
- "&%%(and (not (diary-date 9 25 2003)) (not (diary-date 9 21 2003)) (diary-cyclic 2 9 19 2003)) 09:00-11:30 rrule daily with exceptions\n")
- (icalendar-tests--test-import
- "SUMMARY:rrule weekly
-DTSTART;VALUE=DATE-TIME:20030919T090000
-DTEND;VALUE=DATE-TIME:20030919T113000
-RRULE:FREQ=WEEKLY;
-"
- "&%%(and (diary-cyclic 7 2003 9 19)) 09:00-11:30 rrule weekly\n"
- "&%%(and (diary-cyclic 7 19 9 2003)) 09:00-11:30 rrule weekly\n"
- "&%%(and (diary-cyclic 7 9 19 2003)) 09:00-11:30 rrule weekly\n")
- (icalendar-tests--test-import
- "SUMMARY:rrule monthly no end
-DTSTART;VALUE=DATE-TIME:20030919T090000
-DTEND;VALUE=DATE-TIME:20030919T113000
-RRULE:FREQ=MONTHLY;
-"
- "&%%(and (diary-date t t 19) (diary-block 2003 9 19 9999 1 1)) 09:00-11:30 rrule monthly no end\n"
- "&%%(and (diary-date 19 t t) (diary-block 19 9 2003 1 1 9999)) 09:00-11:30 rrule monthly no end\n"
- "&%%(and (diary-date t 19 t) (diary-block 9 19 2003 1 1 9999)) 09:00-11:30 rrule monthly no end\n")
- (icalendar-tests--test-import
- "SUMMARY:rrule monthly with end
-DTSTART;VALUE=DATE-TIME:20030919T090000
-DTEND;VALUE=DATE-TIME:20030919T113000
-RRULE:FREQ=MONTHLY;UNTIL=20050819;
-"
- "&%%(and (diary-date t t 19) (diary-block 2003 9 19 2005 8 19)) 09:00-11:30 rrule monthly with end\n"
- "&%%(and (diary-date 19 t t) (diary-block 19 9 2003 19 8 2005)) 09:00-11:30 rrule monthly with end\n"
- "&%%(and (diary-date t 19 t) (diary-block 9 19 2003 8 19 2005)) 09:00-11:30 rrule monthly with end\n")
- (icalendar-tests--test-import
- "DTSTART;VALUE=DATE:20040815
-DTEND;VALUE=DATE:20040816
-SUMMARY:Maria Himmelfahrt
-RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=8
-"
- "&%%(and (diary-anniversary 2004 8 15)) Maria Himmelfahrt\n"
- "&%%(and (diary-anniversary 15 8 2004)) Maria Himmelfahrt\n"
- "&%%(and (diary-anniversary 8 15 2004)) Maria Himmelfahrt\n")
- (icalendar-tests--test-import
- "SUMMARY:rrule yearly
-DTSTART;VALUE=DATE-TIME:20030919T090000
-DTEND;VALUE=DATE-TIME:20030919T113000
-RRULE:FREQ=YEARLY;INTERVAL=2
-"
- "&%%(and (diary-anniversary 2003 9 19)) 09:00-11:30 rrule yearly\n" ;FIXME
- "&%%(and (diary-anniversary 19 9 2003)) 09:00-11:30 rrule yearly\n" ;FIXME
- "&%%(and (diary-anniversary 9 19 2003)) 09:00-11:30 rrule yearly\n") ;FIXME
- (icalendar-tests--test-import
- "SUMMARY:rrule count daily short
-DTSTART;VALUE=DATE-TIME:20030919T090000
-DTEND;VALUE=DATE-TIME:20030919T113000
-RRULE:FREQ=DAILY;COUNT=1;INTERVAL=1
-"
- "&%%(and (diary-cyclic 1 2003 9 19) (diary-block 2003 9 19 2003 9 19)) 09:00-11:30 rrule count daily short\n"
- "&%%(and (diary-cyclic 1 19 9 2003) (diary-block 19 9 2003 19 9 2003)) 09:00-11:30 rrule count daily short\n"
- "&%%(and (diary-cyclic 1 9 19 2003) (diary-block 9 19 2003 9 19 2003)) 09:00-11:30 rrule count daily short\n")
- (icalendar-tests--test-import
- "SUMMARY:rrule count daily long
-DTSTART;VALUE=DATE-TIME:20030919T090000
-DTEND;VALUE=DATE-TIME:20030919T113000
-RRULE:FREQ=DAILY;COUNT=14;INTERVAL=1
-"
- "&%%(and (diary-cyclic 1 2003 9 19) (diary-block 2003 9 19 2003 10 2)) 09:00-11:30 rrule count daily long\n"
- "&%%(and (diary-cyclic 1 19 9 2003) (diary-block 19 9 2003 2 10 2003)) 09:00-11:30 rrule count daily long\n"
- "&%%(and (diary-cyclic 1 9 19 2003) (diary-block 9 19 2003 10 2 2003)) 09:00-11:30 rrule count daily long\n")
- (icalendar-tests--test-import
- "SUMMARY:rrule count bi-weekly 3 times
-DTSTART;VALUE=DATE-TIME:20030919T090000
-DTEND;VALUE=DATE-TIME:20030919T113000
-RRULE:FREQ=WEEKLY;COUNT=3;INTERVAL=2
-"
- "&%%(and (diary-cyclic 14 2003 9 19) (diary-block 2003 9 19 2003 10 31)) 09:00-11:30 rrule count bi-weekly 3 times\n"
- "&%%(and (diary-cyclic 14 19 9 2003) (diary-block 19 9 2003 31 10 2003)) 09:00-11:30 rrule count bi-weekly 3 times\n"
- "&%%(and (diary-cyclic 14 9 19 2003) (diary-block 9 19 2003 10 31 2003)) 09:00-11:30 rrule count bi-weekly 3 times\n")
- (icalendar-tests--test-import
- "SUMMARY:rrule count monthly
-DTSTART;VALUE=DATE-TIME:20030919T090000
-DTEND;VALUE=DATE-TIME:20030919T113000
-RRULE:FREQ=MONTHLY;INTERVAL=1;COUNT=5
-"
- "&%%(and (diary-date t t 19) (diary-block 2003 9 19 2004 1 19)) 09:00-11:30 rrule count monthly\n"
- "&%%(and (diary-date 19 t t) (diary-block 19 9 2003 19 1 2004)) 09:00-11:30 rrule count monthly\n"
- "&%%(and (diary-date t 19 t) (diary-block 9 19 2003 1 19 2004)) 09:00-11:30 rrule count monthly\n")
- (icalendar-tests--test-import
- "SUMMARY:rrule count every second month
-DTSTART;VALUE=DATE-TIME:20030919T090000
-DTEND;VALUE=DATE-TIME:20030919T113000
-RRULE:FREQ=MONTHLY;INTERVAL=2;COUNT=5
-"
- "&%%(and (diary-date t t 19) (diary-block 2003 9 19 2004 5 19)) 09:00-11:30 rrule count every second month\n" ;FIXME
- "&%%(and (diary-date 19 t t) (diary-block 19 9 2003 19 5 2004)) 09:00-11:30 rrule count every second month\n" ;FIXME
- "&%%(and (diary-date t 19 t) (diary-block 9 19 2003 5 19 2004)) 09:00-11:30 rrule count every second month\n") ;FIXME
- (icalendar-tests--test-import
- "SUMMARY:rrule count yearly
-DTSTART;VALUE=DATE-TIME:20030919T090000
-DTEND;VALUE=DATE-TIME:20030919T113000
-RRULE:FREQ=YEARLY;INTERVAL=1;COUNT=5
-"
- "&%%(and (diary-date t 9 19) (diary-block 2003 9 19 2007 9 19)) 09:00-11:30 rrule count yearly\n"
- "&%%(and (diary-date 19 9 t) (diary-block 19 9 2003 19 9 2007)) 09:00-11:30 rrule count yearly\n"
- "&%%(and (diary-date 9 19 t) (diary-block 9 19 2003 9 19 2007)) 09:00-11:30 rrule count yearly\n")
- (icalendar-tests--test-import
- "SUMMARY:rrule count every second year
-DTSTART;VALUE=DATE-TIME:20030919T090000
-DTEND;VALUE=DATE-TIME:20030919T113000
-RRULE:FREQ=YEARLY;INTERVAL=2;COUNT=5
-"
- "&%%(and (diary-date t 9 19) (diary-block 2003 9 19 2011 9 19)) 09:00-11:30 rrule count every second year\n" ;FIXME!!!
- "&%%(and (diary-date 19 9 t) (diary-block 19 9 2003 19 9 2011)) 09:00-11:30 rrule count every second year\n" ;FIXME!!!
- "&%%(and (diary-date 9 19 t) (diary-block 9 19 2003 9 19 2011)) 09:00-11:30 rrule count every second year\n") ;FIXME!!!
-)
+ (icalendar-tests--test-import "import-rrule-daily.ics"
+ "import-rrule-daily.diary-iso"
+ "import-rrule-daily.diary-european"
+ "import-rrule-daily.diary-american")
+ (icalendar-tests--test-import "import-rrule-daily-two-day.ics"
+ "import-rrule-daily-two-day.diary-iso"
+ "import-rrule-daily-two-day.diary-european"
+ "import-rrule-daily-two-day.diary-american")
+ (icalendar-tests--test-import "import-rrule-daily-with-exceptions.ics"
+ "import-rrule-daily-with-exceptions.diary-iso"
+ "import-rrule-daily-with-exceptions.diary-european"
+ "import-rrule-daily-with-exceptions.diary-american")
+ (icalendar-tests--test-import "import-rrule-weekly.ics"
+ "import-rrule-weekly.diary-iso"
+ "import-rrule-weekly.diary-european"
+ "import-rrule-weekly.diary-american")
+ (icalendar-tests--test-import "import-rrule-monthly-no-end.ics"
+ "import-rrule-monthly-no-end.diary-iso"
+ "import-rrule-monthly-no-end.diary-european"
+ "import-rrule-monthly-no-end.diary-american")
+ (icalendar-tests--test-import "import-rrule-monthly-with-end.ics"
+ "import-rrule-monthly-with-end.diary-iso"
+ "import-rrule-monthly-with-end.diary-european"
+ "import-rrule-monthly-with-end.diary-american")
+ (icalendar-tests--test-import "import-rrule-anniversary.ics"
+ "import-rrule-anniversary.diary-iso"
+ "import-rrule-anniversary.diary-european"
+ "import-rrule-anniversary.diary-american")
+ (icalendar-tests--test-import "import-rrule-yearly.ics"
+ "import-rrule-yearly.diary-iso"
+ "import-rrule-yearly.diary-european"
+ "import-rrule-yearly.diary-american")
+ (icalendar-tests--test-import "import-rrule-count-daily-short.ics"
+ "import-rrule-count-daily-short.diary-iso"
+ "import-rrule-count-daily-short.diary-european"
+ "import-rrule-count-daily-short.diary-american")
+ (icalendar-tests--test-import "import-rrule-count-daily-long.ics"
+ "import-rrule-count-daily-long.diary-iso"
+ "import-rrule-count-daily-long.diary-european"
+ "import-rrule-count-daily-long.diary-american")
+ (icalendar-tests--test-import "import-rrule-count-monthly.ics"
+ "import-rrule-count-monthly.diary-iso"
+ "import-rrule-count-monthly.diary-european"
+ "import-rrule-count-monthly.diary-american")
+ (icalendar-tests--test-import "import-rrule-count-every-second-month.ics"
+ "import-rrule-count-every-second-month.diary-iso"
+ "import-rrule-count-every-second-month.diary-european"
+ "import-rrule-count-every-second-month.diary-american")
+ (icalendar-tests--test-import "import-rrule-count-yearly.ics"
+ "import-rrule-count-yearly.diary-iso"
+ "import-rrule-count-yearly.diary-european"
+ "import-rrule-count-yearly.diary-american")
+ (icalendar-tests--test-import "import-rrule-count-every-second-year.ics"
+ "import-rrule-count-every-second-year.diary-iso"
+ "import-rrule-count-every-second-year.diary-european"
+ "import-rrule-count-every-second-year.diary-american")
+ )
(ert-deftest icalendar-import-duration ()
- ;; duration
- (icalendar-tests--test-import
- "DTSTART;VALUE=DATE:20050217
-SUMMARY:duration
-DURATION:P7D
-"
- "&%%(and (diary-block 2005 2 17 2005 2 23)) duration\n"
- "&%%(and (diary-block 17 2 2005 23 2 2005)) duration\n"
- "&%%(and (diary-block 2 17 2005 2 23 2005)) duration\n")
- (icalendar-tests--test-import
- "UID:20041127T183329Z-18215-1001-4536-49109@andromeda
-DTSTAMP:20041127T183315Z
-LAST-MODIFIED:20041127T183329
-SUMMARY:Urlaub
-DTSTART;VALUE=DATE:20011221
-DTEND;VALUE=DATE:20011221
-RRULE:FREQ=DAILY;UNTIL=20011229;INTERVAL=1;WKST=SU
-CLASS:PUBLIC
-SEQUENCE:1
-CREATED:20041127T183329
-"
- "&%%(and (diary-cyclic 1 2001 12 21) (diary-block 2001 12 21 2001 12 29)) Urlaub
- Class: PUBLIC
- UID: 20041127T183329Z-18215-1001-4536-49109@andromeda\n"
- "&%%(and (diary-cyclic 1 21 12 2001) (diary-block 21 12 2001 29 12 2001)) Urlaub
- Class: PUBLIC
- UID: 20041127T183329Z-18215-1001-4536-49109@andromeda\n"
- "&%%(and (diary-cyclic 1 12 21 2001) (diary-block 12 21 2001 12 29 2001)) Urlaub
- Class: PUBLIC
- UID: 20041127T183329Z-18215-1001-4536-49109@andromeda\n"))
+ (icalendar-tests--test-import "import-duration.ics"
+ "import-duration.diary-iso"
+ "import-duration.diary-european"
+ "import-duration.diary-american")
+ ;; duration-2: this is actually an rrule test
+ (icalendar-tests--test-import "import-duration-2.ics"
+ "import-duration-2.diary-iso"
+ "import-duration-2.diary-european"
+ "import-duration-2.diary-american"))
(ert-deftest icalendar-import-bug-6766 ()
;;bug#6766 -- multiple byday values in a weekly rrule
- (icalendar-tests--test-import
-"CLASS:PUBLIC
-DTEND;TZID=America/New_York:20100421T120000
-DTSTAMP:20100525T141214Z
-DTSTART;TZID=America/New_York:20100421T113000
-RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,WE,TH,FR
-SEQUENCE:1
-STATUS:CONFIRMED
-SUMMARY:Scrum
-TRANSP:OPAQUE
-UID:8814e3f9-7482-408f-996c-3bfe486a1262
-END:VEVENT
-BEGIN:VEVENT
-CLASS:PUBLIC
-DTSTAMP:20100525T141214Z
-DTSTART;VALUE=DATE:20100422
-DTEND;VALUE=DATE:20100423
-RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=TU,TH
-SEQUENCE:1
-SUMMARY:Tues + Thurs thinking
-TRANSP:OPAQUE
-UID:8814e3f9-7482-408f-996c-3bfe486a1263
-"
-"&%%(and (memq (calendar-day-of-week date) '(1 3 4 5)) (diary-cyclic 1 2010 4 21)) 11:30-12:00 Scrum
- Status: CONFIRMED
- Class: PUBLIC
- UID: 8814e3f9-7482-408f-996c-3bfe486a1262
-&%%(and (memq (calendar-day-of-week date) '(2 4)) (diary-cyclic 1 2010 4 22)) Tues + Thurs thinking
- Class: PUBLIC
- UID: 8814e3f9-7482-408f-996c-3bfe486a1263
-"
-"&%%(and (memq (calendar-day-of-week date) '(1 3 4 5)) (diary-cyclic 1 21 4 2010)) 11:30-12:00 Scrum
- Status: CONFIRMED
- Class: PUBLIC
- UID: 8814e3f9-7482-408f-996c-3bfe486a1262
-&%%(and (memq (calendar-day-of-week date) '(2 4)) (diary-cyclic 1 22 4 2010)) Tues + Thurs thinking
- Class: PUBLIC
- UID: 8814e3f9-7482-408f-996c-3bfe486a1263
-"
-"&%%(and (memq (calendar-day-of-week date) '(1 3 4 5)) (diary-cyclic 1 4 21 2010)) 11:30-12:00 Scrum
- Status: CONFIRMED
- Class: PUBLIC
- UID: 8814e3f9-7482-408f-996c-3bfe486a1262
-&%%(and (memq (calendar-day-of-week date) '(2 4)) (diary-cyclic 1 4 22 2010)) Tues + Thurs thinking
- Class: PUBLIC
- UID: 8814e3f9-7482-408f-996c-3bfe486a1263
-"))
+ (icalendar-tests--test-import "import-bug-6766.ics"
+ "import-bug-6766.diary-iso"
+ "import-bug-6766.diary-european"
+ "import-bug-6766.diary-american"))
(ert-deftest icalendar-import-bug-24199 ()
;;bug#24199 -- monthly rule with byday-clause
- (icalendar-tests--test-import
-"
-SUMMARY:Summary
-DESCRIPTION:Desc
-LOCATION:Loc
-DTSTART:20151202T124600
-DTEND:20151202T160000
-RRULE:FREQ=MONTHLY;BYDAY=1WE;INTERVAL=1
-EXDATE:20160106T114600Z
-EXDATE:20160203T114600Z
-EXDATE:20160302T114600Z
-EXDATE:20160504T104600Z
-EXDATE:20160601T104600Z
-CLASS:DEFAULT
-TRANSP:OPAQUE
-BEGIN:VALARM
-ACTION:DISPLAY
-TRIGGER;VALUE=DURATION:-PT3H
-END:VALARM
-LAST-MODIFIED:20160805T191040Z
-UID:9188710a-08a7-4061-bae3-d4cf4972599a
-"
-"&%%(and (not (diary-date 2016 1 6)) (not (diary-date 2016 2 3)) (not (diary-date 2016 3 2)) (not (diary-date 2016 5 4)) (not (diary-date 2016 6 1)) (diary-float t 3 1) (diary-block 2015 12 2 9999 1 1)) 12:46-16:00 Summary
- Desc: Desc
- Location: Loc
- Class: DEFAULT
- UID: 9188710a-08a7-4061-bae3-d4cf4972599a
-"
-"&%%(and (not (diary-date 6 1 2016)) (not (diary-date 3 2 2016)) (not (diary-date 2 3 2016)) (not (diary-date 4 5 2016)) (not (diary-date 1 6 2016)) (diary-float t 3 1) (diary-block 2 12 2015 1 1 9999)) 12:46-16:00 Summary
- Desc: Desc
- Location: Loc
- Class: DEFAULT
- UID: 9188710a-08a7-4061-bae3-d4cf4972599a
-"
-"&%%(and (not (diary-date 1 6 2016)) (not (diary-date 2 3 2016)) (not (diary-date 3 2 2016)) (not (diary-date 5 4 2016)) (not (diary-date 6 1 2016)) (diary-float t 3 1) (diary-block 12 2 2015 1 1 9999)) 12:46-16:00 Summary
- Desc: Desc
- Location: Loc
- Class: DEFAULT
- UID: 9188710a-08a7-4061-bae3-d4cf4972599a
-"
-))
+ (icalendar-tests--test-import "import-bug-24199.ics"
+ "import-bug-24199.diary-iso"
+ "import-bug-24199.diary-european"
+ "import-bug-24199.diary-american"))
+
+(ert-deftest icalendar-import-bug-33277 ()
+ ;;bug#33277 -- start time equals end time
+ (icalendar-tests--test-import "import-bug-33277.ics"
+ "import-bug-33277.diary-iso"
+ "import-bug-33277.diary-european"
+ "import-bug-33277.diary-american"))
(ert-deftest icalendar-import-multiple-vcalendars ()
- (icalendar-tests--test-import
- "DTSTART;VALUE=DATE:20110723
-SUMMARY:event-1
-"
- "&2011/7/23 event-1\n"
- "&23/7/2011 event-1\n"
- "&7/23/2011 event-1\n")
-
- (icalendar-tests--test-import
- "BEGIN:VCALENDAR
-PRODID:-//Emacs//NONSGML icalendar.el//EN
-VERSION:2.0\nBEGIN:VEVENT
-DTSTART;VALUE=DATE:20110723
-SUMMARY:event-1
-END:VEVENT
-END:VCALENDAR
-BEGIN:VCALENDAR
-PRODID:-//Emacs//NONSGML icalendar.el//EN
-VERSION:2.0
-BEGIN:VEVENT
-DTSTART;VALUE=DATE:20110724
-SUMMARY:event-2
-END:VEVENT
-END:VCALENDAR
-BEGIN:VCALENDAR
-PRODID:-//Emacs//NONSGML icalendar.el//EN
-VERSION:2.0
-BEGIN:VEVENT
-DTSTART;VALUE=DATE:20110725
-SUMMARY:event-3a
-END:VEVENT
-BEGIN:VEVENT
-DTSTART;VALUE=DATE:20110725
-SUMMARY:event-3b
-END:VEVENT
-END:VCALENDAR
-"
- "&2011/7/23 event-1\n&2011/7/24 event-2\n&2011/7/25 event-3a\n&2011/7/25 event-3b\n"
- "&23/7/2011 event-1\n&24/7/2011 event-2\n&25/7/2011 event-3a\n&25/7/2011 event-3b\n"
- "&7/23/2011 event-1\n&7/24/2011 event-2\n&7/25/2011 event-3a\n&7/25/2011 event-3b\n"))
+ (icalendar-tests--test-import "import-multiple-vcalendars.ics"
+ "import-multiple-vcalendars.diary-iso"
+ "import-multiple-vcalendars.diary-european"
+ "import-multiple-vcalendars.diary-american"))
(ert-deftest icalendar-import-with-uid ()
"Perform import test with uid."
- (icalendar-tests--test-import
- "UID:1234567890uid
-SUMMARY:non-recurring
-DTSTART;VALUE=DATE-TIME:20030919T090000
-DTEND;VALUE=DATE-TIME:20030919T113000"
- "&2003/9/19 09:00-11:30 non-recurring\n UID: 1234567890uid\n"
- "&19/9/2003 09:00-11:30 non-recurring\n UID: 1234567890uid\n"
- "&9/19/2003 09:00-11:30 non-recurring\n UID: 1234567890uid\n"))
+ (icalendar-tests--test-import "import-with-uid.ics"
+ "import-with-uid.diary-iso"
+ "import-with-uid.diary-european"
+ "import-with-uid.diary-american"))
(ert-deftest icalendar-import-with-timezone ()
;; This is known to fail on MS-Windows, because the test assumes
@@ -1361,42 +1203,13 @@ DTEND;VALUE=DATE-TIME:20030919T113000"
:failed
:passed)
;; bug#11473
- (icalendar-tests--test-import
- "BEGIN:VCALENDAR
-BEGIN:VTIMEZONE
-TZID:fictional, nonexistent, arbitrary
-BEGIN:STANDARD
-DTSTART:20100101T000000
-TZOFFSETFROM:+0200
-TZOFFSETTO:-0200
-RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=01
-END:STANDARD
-BEGIN:DAYLIGHT
-DTSTART:20101201T000000
-TZOFFSETFROM:-0200
-TZOFFSETTO:+0200
-RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=1SU;BYMONTH=11
-END:DAYLIGHT
-END:VTIMEZONE
-BEGIN:VEVENT
-SUMMARY:standardtime
-DTSTART;TZID=\"fictional, nonexistent, arbitrary\":20120115T120000
-DTEND;TZID=\"fictional, nonexistent, arbitrary\":20120115T123000
-END:VEVENT
-BEGIN:VEVENT
-SUMMARY:daylightsavingtime
-DTSTART;TZID=\"fictional, nonexistent, arbitrary\":20121215T120000
-DTEND;TZID=\"fictional, nonexistent, arbitrary\":20121215T123000
-END:VEVENT
-END:VCALENDAR"
- ;; "standardtime" begins first sunday in january and is 4 hours behind CET
- ;; "daylightsavingtime" begins first sunday in november and is 1 hour before CET
- "&2012/1/15 15:00-15:30 standardtime
-&2012/12/15 11:00-11:30 daylightsavingtime
-"
- nil
- nil)
- )
+ ;; "standardtime" begins first sunday in january and is 4 hours behind CET
+ ;; "daylightsavingtime" begins first sunday in november and is 1 hour before CET
+ (icalendar-tests--test-import "import-with-timezone.ics"
+ "import-with-timezone.diary-iso"
+ nil
+ nil))
+
;; ======================================================================
;; Cycle
;; ======================================================================
@@ -1427,35 +1240,33 @@ Argument INPUT icalendar event string."
(defun icalendar-tests--do-test-cycle ()
"Actually perform import/export cycle test."
- (let ((temp-diary (make-temp-file "icalendar-test-diary"))
- (temp-ics (make-temp-file "icalendar-test-ics"))
- (org-input (buffer-substring-no-properties (point-min) (point-max))))
-
- (unwind-protect
- (progn
- ;; step 1: import
- (icalendar-import-buffer temp-diary t t)
-
- ;; step 2: export what was just imported
- (save-excursion
- (find-file temp-diary)
- (icalendar-export-region (point-min) (point-max) temp-ics))
-
- ;; compare the output of step 2 with the input of step 1
- (save-excursion
- (find-file temp-ics)
- (goto-char (point-min))
- ;;(when (re-search-forward "\nUID:.*\n" nil t)
- ;;(replace-match "\n"))
- (let ((cycled (buffer-substring-no-properties (point-min) (point-max))))
- (should (string= org-input cycled)))))
- ;; clean up
- (kill-buffer (find-buffer-visiting temp-diary))
- (with-current-buffer (find-buffer-visiting temp-ics)
- (set-buffer-modified-p nil)
- (kill-buffer (current-buffer)))
- (delete-file temp-diary)
- (delete-file temp-ics))))
+ (ert-with-temp-file temp-diary
+ (ert-with-temp-file temp-ics
+ (let ((org-input (buffer-substring-no-properties (point-min) (point-max))))
+
+ (unwind-protect
+ (progn
+ ;; step 1: import
+ (icalendar-import-buffer temp-diary t t)
+
+ ;; step 2: export what was just imported
+ (save-excursion
+ (find-file temp-diary)
+ (icalendar-export-region (point-min) (point-max) temp-ics))
+
+ ;; compare the output of step 2 with the input of step 1
+ (save-excursion
+ (find-file temp-ics)
+ (goto-char (point-min))
+ ;;(when (re-search-forward "\nUID:.*\n" nil t)
+ ;;(replace-match "\n"))
+ (let ((cycled (buffer-substring-no-properties (point-min) (point-max))))
+ (should (string= org-input cycled)))))
+ ;; clean up
+ (kill-buffer (find-buffer-visiting temp-diary))
+ (with-current-buffer (find-buffer-visiting temp-ics)
+ (set-buffer-modified-p nil)
+ (kill-buffer (current-buffer))))))))
(ert-deftest icalendar-cycle ()
"Perform cycling tests.
@@ -1475,8 +1286,8 @@ DESCRIPTION:beschreibung!
LOCATION:nowhere
ORGANIZER:ulf
")
- (icalendar-tests--test-cycle
- "UID:4711
+ (icalendar-tests--test-cycle
+ "UID:4711
DTSTART;VALUE=DATE:19190909
DTEND;VALUE=DATE:19190910
RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=09;BYMONTHDAY=09
@@ -1494,237 +1305,27 @@ SUMMARY:and diary-anniversary
:failed
:passed)
;; 2003-05-29
- (icalendar-tests--test-import
- "BEGIN:VCALENDAR
-METHOD:REQUEST
-PRODID:Microsoft CDO for Microsoft Exchange
-VERSION:2.0
-BEGIN:VTIMEZONE
-TZID:Kolkata, Chennai, Mumbai, New Delhi
-X-MICROSOFT-CDO-TZID:23
-BEGIN:STANDARD
-DTSTART:16010101T000000
-TZOFFSETFROM:+0530
-TZOFFSETTO:+0530
-END:STANDARD
-BEGIN:DAYLIGHT
-DTSTART:16010101T000000
-TZOFFSETFROM:+0530
-TZOFFSETTO:+0530
-END:DAYLIGHT
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20030509T043439Z
-DTSTART;TZID=\"Kolkata, Chennai, Mumbai, New Delhi\":20030509T103000
-SUMMARY:On-Site Interview
-UID:040000008200E00074C5B7101A82E0080000000080B6DE661216C301000000000000000
- 010000000DB823520692542408ED02D7023F9DFF9
-ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=\"Xxxxx
- xxx Xxxxxxxxxxxx\":MAILTO:xxxxxxxx@xxxxxxx.com
-ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=\"Yyyyyyy Y
- yyyy\":MAILTO:yyyyyyy@yyyyyyy.com
-ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=\"Zzzz Zzzz
- zz\":MAILTO:zzzzzz@zzzzzzz.com
-ORGANIZER;CN=\"Aaaaaa Aaaaa\":MAILTO:aaaaaaa@aaaaaaa.com
-LOCATION:Cccc
-DTEND;TZID=\"Kolkata, Chennai, Mumbai, New Delhi\":20030509T153000
-DESCRIPTION:10:30am - Blah
-SEQUENCE:0
-PRIORITY:5
-CLASS:
-CREATED:20030509T043439Z
-LAST-MODIFIED:20030509T043459Z
-STATUS:CONFIRMED
-TRANSP:OPAQUE
-X-MICROSOFT-CDO-BUSYSTATUS:BUSY
-X-MICROSOFT-CDO-INSTTYPE:0
-X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY
-X-MICROSOFT-CDO-ALLDAYEVENT:FALSE
-X-MICROSOFT-CDO-IMPORTANCE:1
-X-MICROSOFT-CDO-OWNERAPPTID:126441427
-BEGIN:VALARM
-ACTION:DISPLAY
-DESCRIPTION:REMINDER
-TRIGGER;RELATED=START:-PT00H15M00S
-END:VALARM
-END:VEVENT
-END:VCALENDAR"
- nil
- "&9/5/2003 07:00-12:00 On-Site Interview
- Desc: 10:30am - Blah
- Location: Cccc
- Organizer: MAILTO:aaaaaaa@aaaaaaa.com
- Status: CONFIRMED
- UID: 040000008200E00074C5B7101A82E0080000000080B6DE661216C301000000000000000010000000DB823520692542408ED02D7023F9DFF9
-"
- "&5/9/2003 07:00-12:00 On-Site Interview
- Desc: 10:30am - Blah
- Location: Cccc
- Organizer: MAILTO:aaaaaaa@aaaaaaa.com
- Status: CONFIRMED
- UID: 040000008200E00074C5B7101A82E0080000000080B6DE661216C301000000000000000010000000DB823520692542408ED02D7023F9DFF9
-")
+ (icalendar-tests--test-import "import-real-world-2003-05-29.ics"
+ nil
+ "import-real-world-2003-05-29.diary-european"
+ "import-real-world-2003-05-29.diary-american")
;; created with http://apps.marudot.com/ical/
- (icalendar-tests--test-import
- "BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//www.marudot.com//iCal Event Maker
-X-WR-CALNAME:Test
-CALSCALE:GREGORIAN
-BEGIN:VTIMEZONE
-TZID:Asia/Tehran
-TZURL:http://tzurl.org/zoneinfo-outlook/Asia/Tehran
-X-LIC-LOCATION:Asia/Tehran
-BEGIN:STANDARD
-TZOFFSETFROM:+0330
-TZOFFSETTO:+0330
-TZNAME:IRST
-DTSTART:19700101T000000
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20141116T171439Z
-UID:20141116T171439Z-678877132@marudot.com
-DTSTART;TZID=\"Asia/Tehran\":20141116T070000
-DTEND;TZID=\"Asia/Tehran\":20141116T080000
-SUMMARY:NoDST
-DESCRIPTION:Test event from timezone without DST
-LOCATION:Everywhere
-END:VEVENT
-END:VCALENDAR"
- nil
- "&16/11/2014 04:30-05:30 NoDST
- Desc: Test event from timezone without DST
- Location: Everywhere
- UID: 20141116T171439Z-678877132@marudot.com
-"
- "&11/16/2014 04:30-05:30 NoDST
- Desc: Test event from timezone without DST
- Location: Everywhere
- UID: 20141116T171439Z-678877132@marudot.com
-")
-
+ (icalendar-tests--test-import "import-real-world-no-dst.ics"
+ nil
+ "import-real-world-no-dst.diary-european"
+ "import-real-world-no-dst.diary-american")
;; 2003-06-18 a
- (icalendar-tests--test-import
- "DTSTAMP:20030618T195512Z
-DTSTART;TZID=\"Mountain Time (US & Canada)\":20030623T110000
-SUMMARY:Dress Rehearsal for XXXX-XXXX
-UID:040000008200E00074C5B7101A82E00800000000608AA7DA9835C301000000000000000
- 0100000007C3A6D65EE726E40B7F3D69A23BD567E
-ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=\"AAAAA,AAA
- AA (A-AAAAAAA,ex1)\":MAILTO:aaaaa_aaaaa@aaaaa.com
-ORGANIZER;CN=\"ABCD,TECHTRAINING
- (A-Americas,exgen1)\":MAILTO:xxx@xxxxx.com
-LOCATION:555 or TN 555-5555 ID 5555 & NochWas (see below)
-DTEND;TZID=\"Mountain Time (US & Canada)\":20030623T120000
-DESCRIPTION:753 Zeichen hier radiert
-SEQUENCE:0
-PRIORITY:5
-CLASS:
-CREATED:20030618T195518Z
-LAST-MODIFIED:20030618T195527Z
-STATUS:CONFIRMED
-TRANSP:OPAQUE
-X-MICROSOFT-CDO-BUSYSTATUS:BUSY
-X-MICROSOFT-CDO-INSTTYPE:0
-X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY
-X-MICROSOFT-CDO-ALLDAYEVENT:FALSE
-X-MICROSOFT-CDO-IMPORTANCE:1
-X-MICROSOFT-CDO-OWNERAPPTID:1022519251
-BEGIN:VALARM
-ACTION:DISPLAY
-DESCRIPTION:REMINDER
-TRIGGER;RELATED=START:-PT00H15M00S
-END:VALARM"
- nil
- "&23/6/2003 11:00-12:00 Dress Rehearsal for XXXX-XXXX
- Desc: 753 Zeichen hier radiert
- Location: 555 or TN 555-5555 ID 5555 & NochWas (see below)
- Organizer: MAILTO:xxx@xxxxx.com
- Status: CONFIRMED
- UID: 040000008200E00074C5B7101A82E00800000000608AA7DA9835C3010000000000000000100000007C3A6D65EE726E40B7F3D69A23BD567E
-"
- "&6/23/2003 11:00-12:00 Dress Rehearsal for XXXX-XXXX
- Desc: 753 Zeichen hier radiert
- Location: 555 or TN 555-5555 ID 5555 & NochWas (see below)
- Organizer: MAILTO:xxx@xxxxx.com
- Status: CONFIRMED
- UID: 040000008200E00074C5B7101A82E00800000000608AA7DA9835C3010000000000000000100000007C3A6D65EE726E40B7F3D69A23BD567E
-")
+ (icalendar-tests--test-import "import-real-world-2003-06-18a.ics"
+ nil
+ "import-real-world-2003-06-18a.diary-european"
+ "import-real-world-2003-06-18a.diary-american")
;; 2003-06-18 b -- uses timezone
- (icalendar-tests--test-import
- "BEGIN:VCALENDAR
-METHOD:REQUEST
-PRODID:Microsoft CDO for Microsoft Exchange
-VERSION:2.0
-BEGIN:VTIMEZONE
-TZID:Mountain Time (US & Canada)
-X-MICROSOFT-CDO-TZID:12
-BEGIN:STANDARD
-DTSTART:16010101T020000
-TZOFFSETFROM:-0600
-TZOFFSETTO:-0700
-RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=10;BYDAY=-1SU
-END:STANDARD
-BEGIN:DAYLIGHT
-DTSTART:16010101T020000
-TZOFFSETFROM:-0700
-TZOFFSETTO:-0600
-RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=4;BYDAY=1SU
-END:DAYLIGHT
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20030618T230323Z
-DTSTART;TZID=\"Mountain Time (US & Canada)\":20030623T090000
-SUMMARY:Updated: Dress Rehearsal for ABC01-15
-UID:040000008200E00074C5B7101A82E00800000000608AA7DA9835C301000000000000000
- 0100000007C3A6D65EE726E40B7F3D69A23BD567E
-ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;X-REPLYTIME=20030618T20
- 0700Z;RSVP=TRUE;CN=\"AAAAA,AAAAAA
-\(A-AAAAAAA,ex1)\":MAILTO:aaaaaa_aaaaa@aaaaa
- .com
-ORGANIZER;CN=\"ABCD,TECHTRAINING
-\(A-Americas,exgen1)\":MAILTO:bbb@bbbbb.com
-LOCATION:123 or TN 123-1234 ID abcd & SonstWo (see below)
-DTEND;TZID=\"Mountain Time (US & Canada)\":20030623T100000
-DESCRIPTION:Viele Zeichen standen hier früher
-SEQUENCE:0
-PRIORITY:5
-CLASS:
-CREATED:20030618T230326Z
-LAST-MODIFIED:20030618T230335Z
-STATUS:CONFIRMED
-TRANSP:OPAQUE
-X-MICROSOFT-CDO-BUSYSTATUS:BUSY
-X-MICROSOFT-CDO-INSTTYPE:0
-X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY
-X-MICROSOFT-CDO-ALLDAYEVENT:FALSE
-X-MICROSOFT-CDO-IMPORTANCE:1
-X-MICROSOFT-CDO-OWNERAPPTID:1022519251
-BEGIN:VALARM
-ACTION:DISPLAY
-DESCRIPTION:REMINDER
-TRIGGER;RELATED=START:-PT00H15M00S
-END:VALARM
-END:VEVENT
-END:VCALENDAR"
- nil
- "&23/6/2003 17:00-18:00 Updated: Dress Rehearsal for ABC01-15
- Desc: Viele Zeichen standen hier früher
- Location: 123 or TN 123-1234 ID abcd & SonstWo (see below)
- Organizer: MAILTO:bbb@bbbbb.com
- Status: CONFIRMED
- UID: 040000008200E00074C5B7101A82E00800000000608AA7DA9835C3010000000000000000100000007C3A6D65EE726E40B7F3D69A23BD567E
-"
- "&6/23/2003 17:00-18:00 Updated: Dress Rehearsal for ABC01-15
- Desc: Viele Zeichen standen hier früher
- Location: 123 or TN 123-1234 ID abcd & SonstWo (see below)
- Organizer: MAILTO:bbb@bbbbb.com
- Status: CONFIRMED
- UID: 040000008200E00074C5B7101A82E00800000000608AA7DA9835C3010000000000000000100000007C3A6D65EE726E40B7F3D69A23BD567E
-")
+ (icalendar-tests--test-import "import-real-world-2003-06-18b.ics"
+ nil
+ "import-real-world-2003-06-18b.diary-european"
+ "import-real-world-2003-06-18b.diary-american")
;; export 2004-10-28 block entries
(icalendar-tests--test-export
nil
@@ -1786,7 +1387,7 @@ SUMMARY:ff")
"
>>> anniversaries:
-%%(diary-anniversary 3 28 1991) aa birthday (%d years old)"
+%%(diary-anniversary 3 28 1990) aa birthday (%d years old)"
"DTSTART;VALUE=DATE:19910328
DTEND;VALUE=DATE:19910329
RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=03;BYMONTHDAY=28
@@ -1796,7 +1397,7 @@ SUMMARY:aa birthday (%d years old)
(icalendar-tests--test-export
nil
nil
- "%%(diary-anniversary 5 17 1957) bb birthday (%d years old)"
+ "%%(diary-anniversary 5 17 1956) bb birthday (%d years old)"
"DTSTART;VALUE=DATE:19570517
DTEND;VALUE=DATE:19570518
RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=05;BYMONTHDAY=17
@@ -1805,7 +1406,7 @@ SUMMARY:bb birthday (%d years old)")
(icalendar-tests--test-export
nil
nil
- "%%(diary-anniversary 6 8 1997) cc birthday (%d years old)"
+ "%%(diary-anniversary 6 8 1996) cc birthday (%d years old)"
"DTSTART;VALUE=DATE:19970608
DTEND;VALUE=DATE:19970609
RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=06;BYMONTHDAY=08
@@ -1814,7 +1415,7 @@ SUMMARY:cc birthday (%d years old)")
(icalendar-tests--test-export
nil
nil
- "%%(diary-anniversary 7 22 1983) dd (%d years ago...!)"
+ "%%(diary-anniversary 7 22 1982) dd (%d years ago...!)"
"DTSTART;VALUE=DATE:19830722
DTEND;VALUE=DATE:19830723
RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=07;BYMONTHDAY=22
@@ -1823,7 +1424,7 @@ SUMMARY:dd (%d years ago...!)")
(icalendar-tests--test-export
nil
nil
- "%%(diary-anniversary 8 1 1988) ee birthday (%d years old)"
+ "%%(diary-anniversary 8 1 1987) ee birthday (%d years old)"
"DTSTART;VALUE=DATE:19880801
DTEND;VALUE=DATE:19880802
RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=08;BYMONTHDAY=01
@@ -1832,13 +1433,20 @@ SUMMARY:ee birthday (%d years old)")
(icalendar-tests--test-export
nil
nil
- "%%(diary-anniversary 9 21 1957) ff birthday (%d years old)"
+ "%%(diary-anniversary 9 21 1956) ff birthday (%d years old)"
"DTSTART;VALUE=DATE:19570921
DTEND;VALUE=DATE:19570922
RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=09;BYMONTHDAY=21
SUMMARY:ff birthday (%d years old)")
+ (icalendar-tests--test-export
+ nil
+ nil
+ "%%(diary-offset '(diary-float t 3 4) 1) asdf"
+ nil)
+
+
;; FIXME!
;; export 2004-10-28 monthly, weekly entries
@@ -1940,169 +1548,10 @@ DTEND;VALUE=DATE-TIME:20041012T150000
SUMMARY:Tue: [2004-10-12] q1")
;; 2004-11-19
- (icalendar-tests--test-import
- "BEGIN:VCALENDAR
-VERSION
- :2.0
-PRODID
- :-//Mozilla.org/NONSGML Mozilla Calendar V1.0//EN
-BEGIN:VEVENT
-SUMMARY
- :Jjjjj & Wwwww
-STATUS
- :TENTATIVE
-CLASS
- :PRIVATE
-X-MOZILLA-ALARM-DEFAULT-LENGTH
- :0
-DTSTART
- :20041123T140000
-DTEND
- :20041123T143000
-DTSTAMP
- :20041118T013430Z
-LAST-MODIFIED
- :20041118T013640Z
-END:VEVENT
-BEGIN:VEVENT
-SUMMARY
- :BB Aaaaaaaa Bbbbb
-STATUS
- :TENTATIVE
-CLASS
- :PRIVATE
-X-MOZILLA-ALARM-DEFAULT-LENGTH
- :0
-DTSTART
- :20041123T144500
-DTEND
- :20041123T154500
-DTSTAMP
- :20041118T013641Z
-END:VEVENT
-BEGIN:VEVENT
-SUMMARY
- :Hhhhhhhh
-STATUS
- :TENTATIVE
-CLASS
- :PRIVATE
-X-MOZILLA-ALARM-DEFAULT-LENGTH
- :0
-DTSTART
- :20041123T110000
-DTEND
- :20041123T120000
-DTSTAMP
- :20041118T013831Z
-END:VEVENT
-BEGIN:VEVENT
-SUMMARY
- :MMM Aaaaaaaaa
-STATUS
- :TENTATIVE
-CLASS
- :PRIVATE
-X-MOZILLA-ALARM-DEFAULT-LENGTH
- :0
-X-MOZILLA-RECUR-DEFAULT-INTERVAL
- :2
-RRULE
- :FREQ=WEEKLY;INTERVAL=2;BYDAY=FR
-DTSTART
- :20041112T140000
-DTEND
- :20041112T183000
-DTSTAMP
- :20041118T014117Z
-END:VEVENT
-BEGIN:VEVENT
-SUMMARY
- :Rrrr/Cccccc ii Aaaaaaaa
-DESCRIPTION
- :Vvvvv Rrrr aaa Cccccc
-STATUS
- :TENTATIVE
-CLASS
- :PRIVATE
-X-MOZILLA-ALARM-DEFAULT-LENGTH
- :0
-DTSTART
- ;VALUE=DATE
- :20041119
-DTEND
- ;VALUE=DATE
- :20041120
-DTSTAMP
- :20041118T013107Z
-LAST-MODIFIED
- :20041118T014203Z
-END:VEVENT
-BEGIN:VEVENT
-SUMMARY
- :Wwww aa hhhh
-STATUS
- :TENTATIVE
-CLASS
- :PRIVATE
-X-MOZILLA-ALARM-DEFAULT-LENGTH
- :0
-RRULE
- :FREQ=WEEKLY;INTERVAL=1;BYDAY=MO
-DTSTART
- ;VALUE=DATE
- :20041101
-DTEND
- ;VALUE=DATE
- :20041102
-DTSTAMP
- :20041118T014045Z
-LAST-MODIFIED
- :20041118T023846Z
-END:VEVENT
-END:VCALENDAR
-"
- nil
- "&23/11/2004 14:00-14:30 Jjjjj & Wwwww
- Status: TENTATIVE
- Class: PRIVATE
-&23/11/2004 14:45-15:45 BB Aaaaaaaa Bbbbb
- Status: TENTATIVE
- Class: PRIVATE
-&23/11/2004 11:00-12:00 Hhhhhhhh
- Status: TENTATIVE
- Class: PRIVATE
-&%%(and (diary-cyclic 14 12 11 2004)) 14:00-18:30 MMM Aaaaaaaaa
- Status: TENTATIVE
- Class: PRIVATE
-&%%(and (diary-block 19 11 2004 19 11 2004)) Rrrr/Cccccc ii Aaaaaaaa
- Desc: Vvvvv Rrrr aaa Cccccc
- Status: TENTATIVE
- Class: PRIVATE
-&%%(and (diary-cyclic 7 1 11 2004)) Wwww aa hhhh
- Status: TENTATIVE
- Class: PRIVATE
-"
- "&11/23/2004 14:00-14:30 Jjjjj & Wwwww
- Status: TENTATIVE
- Class: PRIVATE
-&11/23/2004 14:45-15:45 BB Aaaaaaaa Bbbbb
- Status: TENTATIVE
- Class: PRIVATE
-&11/23/2004 11:00-12:00 Hhhhhhhh
- Status: TENTATIVE
- Class: PRIVATE
-&%%(and (diary-cyclic 14 11 12 2004)) 14:00-18:30 MMM Aaaaaaaaa
- Status: TENTATIVE
- Class: PRIVATE
-&%%(and (diary-block 11 19 2004 11 19 2004)) Rrrr/Cccccc ii Aaaaaaaa
- Desc: Vvvvv Rrrr aaa Cccccc
- Status: TENTATIVE
- Class: PRIVATE
-&%%(and (diary-cyclic 7 11 1 2004)) Wwww aa hhhh
- Status: TENTATIVE
- Class: PRIVATE
-")
+ (icalendar-tests--test-import "import-real-world-2004-11-19.ics"
+ nil
+ "import-real-world-2004-11-19.diary-european"
+ "import-real-world-2004-11-19.diary-american")
;; 2004-09-09 pg
(icalendar-tests--test-export
@@ -2132,53 +1581,16 @@ DTEND;VALUE=DATE-TIME:20041102T163000
SUMMARY:Zahnarzt")
;; 2005-02-07 lt
- (icalendar-tests--test-import
- "UID
- :b60d398e-1dd1-11b2-a159-cf8cb05139f4
-SUMMARY
- :Waitangi Day
-DESCRIPTION
- :abcdef
-CATEGORIES
- :Public Holiday
-STATUS
- :CONFIRMED
-CLASS
- :PRIVATE
-DTSTART
- ;VALUE=DATE
- :20050206
-DTEND
- ;VALUE=DATE
- :20050207
-DTSTAMP
- :20050128T011209Z"
- nil
- "&%%(and (diary-block 6 2 2005 6 2 2005)) Waitangi Day
- Desc: abcdef
- Status: CONFIRMED
- Class: PRIVATE
- UID: b60d398e-1dd1-11b2-a159-cf8cb05139f4
-"
- "&%%(and (diary-block 2 6 2005 2 6 2005)) Waitangi Day
- Desc: abcdef
- Status: CONFIRMED
- Class: PRIVATE
- UID: b60d398e-1dd1-11b2-a159-cf8cb05139f4
-")
+ (icalendar-tests--test-import "import-real-world-2005-02-07.ics"
+ nil
+ "import-real-world-2005-02-07.diary-european"
+ "import-real-world-2005-02-07.diary-american")
;; 2005-03-01 lt
- (icalendar-tests--test-import
- "DTSTART;VALUE=DATE:20050217
-SUMMARY:Hhhhhh Aaaaa ii Aaaaaaaa
-UID:6AFA7558-6994-11D9-8A3A-000A95A0E830-RID
-DTSTAMP:20050118T210335Z
-DURATION:P7D"
- nil
- "&%%(and (diary-block 17 2 2005 23 2 2005)) Hhhhhh Aaaaa ii Aaaaaaaa
- UID: 6AFA7558-6994-11D9-8A3A-000A95A0E830-RID\n"
- "&%%(and (diary-block 2 17 2005 2 23 2005)) Hhhhhh Aaaaa ii Aaaaaaaa
- UID: 6AFA7558-6994-11D9-8A3A-000A95A0E830-RID\n")
+ (icalendar-tests--test-import "import-real-world-2005-03-01.ics"
+ nil
+ "import-real-world-2005-03-01.diary-european"
+ "import-real-world-2005-03-01.diary-american")
;; 2005-03-23 lt
(icalendar-tests--test-export
@@ -2205,126 +1617,46 @@ SUMMARY:NNN Wwwwwwww Wwwww - Aaaaaa Pppppppp rrrrrr ddd oo Nnnnnnnn 30
")
;; bug#11473
- (icalendar-tests--test-import
- "BEGIN:VCALENDAR
-METHOD:REQUEST
-PRODID:Microsoft Exchange Server 2007
-VERSION:2.0
-BEGIN:VTIMEZONE
-TZID:(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna
-BEGIN:STANDARD
-DTSTART:16010101T030000
-TZOFFSETFROM:+0200
-TZOFFSETTO:+0100
-RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10
-END:STANDARD
-BEGIN:DAYLIGHT
-DTSTART:16010101T020000
-TZOFFSETFROM:+0100
-TZOFFSETTO:+0200
-RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3
-END:DAYLIGHT
-END:VTIMEZONE
-BEGIN:VEVENT
-ORGANIZER;CN=\"A. Luser\":MAILTO:a.luser@foo.com
-ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=\"Luser, Oth
- er\":MAILTO:other.luser@foo.com
-DESCRIPTION;LANGUAGE=en-US:\nWhassup?\n\n
-SUMMARY;LANGUAGE=en-US:Query
-DTSTART;TZID=\"(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna\"
- :20120515T150000
-DTEND;TZID=\"(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna\":2
- 0120515T153000
-UID:040000008200E00074C5B7101A82E0080000000020FFAED0CFEFCC01000000000000000
- 010000000575268034ECDB649A15349B1BF240F15
-RECURRENCE-ID;TZID=\"(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, V
- ienna\":20120515T170000
-CLASS:PUBLIC
-PRIORITY:5
-DTSTAMP:20120514T153645Z
-TRANSP:OPAQUE
-STATUS:CONFIRMED
-SEQUENCE:15
-LOCATION;LANGUAGE=en-US:phone
-X-MICROSOFT-CDO-APPT-SEQUENCE:15
-X-MICROSOFT-CDO-OWNERAPPTID:1907632092
-X-MICROSOFT-CDO-BUSYSTATUS:TENTATIVE
-X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY
-X-MICROSOFT-CDO-ALLDAYEVENT:FALSE
-X-MICROSOFT-CDO-IMPORTANCE:1
-X-MICROSOFT-CDO-INSTTYPE:3
-BEGIN:VALARM
-ACTION:DISPLAY
-DESCRIPTION:REMINDER
-TRIGGER;RELATED=START:-PT15M
-END:VALARM
-END:VEVENT
-END:VCALENDAR"
- nil
- "&15/5/2012 15:00-15:30 Query
- Location: phone
- Organizer: MAILTO:a.luser@foo.com
- Status: CONFIRMED
- Class: PUBLIC
- UID: 040000008200E00074C5B7101A82E0080000000020FFAED0CFEFCC01000000000000000010000000575268034ECDB649A15349B1BF240F15
-" nil)
+ (icalendar-tests--test-import "import-bug-11473.ics"
+ nil
+ "import-bug-11473.diary-european"
+ nil)
;; 2015-12-05, mixed line endings and empty lines, see Bug#22092.
- (icalendar-tests--test-import
- "BEGIN:VCALENDAR\r
-PRODID:-//www.norwegian.no//iCalendar MIMEDIR//EN\r
-VERSION:2.0\r
-METHOD:REQUEST\r
-BEGIN:VEVENT\r
-UID:RFCALITEM1\r
-SEQUENCE:1512040950\r
-DTSTAMP:20141204T095043Z\r
-ORGANIZER:noreply@norwegian.no\r
-DTSTART:20141208T173000Z\r
-
-DTEND:20141208T215500Z\r
-
-LOCATION:Stavanger-Sola\r
-
-DESCRIPTION:Fly med Norwegian, reservasjon. Fra Stavanger til Troms&#248; 8. des 2014 18:30, DY545Fly med Norwegian, reservasjon . Fra Stavanger til Troms&#248; 8. des 2014 21:00, DY390\r
-
-X-ALT-DESC;FMTTYPE=text/html:<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\"><html><head><META NAME=\"Generator\" CONTENT=\"MS Exchange Server version 08.00.0681.000\"><title></title></head><body><b><font face=\"Calibri\" size=\"3\">Reisereferanse</p></body></html>
-SUMMARY:Norwegian til Tromsoe-Langnes -\r
-
-CATEGORIES:Appointment\r
-
-
-PRIORITY:5\r
+ (icalendar-tests--test-import "import-bug-22092.ics"
+ "import-bug-22092.diary-iso"
+ "import-bug-22092.diary-european"
+ "import-bug-22092.diary-american"))
-CLASS:PUBLIC\r
+(defun icalendar-test--format (string &optional day zone)
+ "Decode and format STRING with DAY and ZONE."
+ (let ((time (icalendar--decode-isodatetime string day zone)))
+ (format-time-string "%FT%T%z" (encode-time time) 0)))
-TRANSP:OPAQUE\r
-END:VEVENT\r
-END:VCALENDAR
-"
-"&2014/12/8 18:30-22:55 Norwegian til Tromsoe-Langnes -
- Desc: Fly med Norwegian, reservasjon. Fra Stavanger til Troms&#248; 8. des 2014 18:30, DY545Fly med Norwegian, reservasjon . Fra Stavanger til Troms&#248; 8. des 2014 21:00, DY390
- Location: Stavanger-Sola
- Organizer: noreply@norwegian.no
- Class: PUBLIC
- UID: RFCALITEM1
-"
-"&8/12/2014 18:30-22:55 Norwegian til Tromsoe-Langnes -
- Desc: Fly med Norwegian, reservasjon. Fra Stavanger til Troms&#248; 8. des 2014 18:30, DY545Fly med Norwegian, reservasjon . Fra Stavanger til Troms&#248; 8. des 2014 21:00, DY390
- Location: Stavanger-Sola
- Organizer: noreply@norwegian.no
- Class: PUBLIC
- UID: RFCALITEM1
-"
-"&12/8/2014 18:30-22:55 Norwegian til Tromsoe-Langnes -
- Desc: Fly med Norwegian, reservasjon. Fra Stavanger til Troms&#248; 8. des 2014 18:30, DY545Fly med Norwegian, reservasjon . Fra Stavanger til Troms&#248; 8. des 2014 21:00, DY390
- Location: Stavanger-Sola
- Organizer: noreply@norwegian.no
- Class: PUBLIC
- UID: RFCALITEM1
-"
-)
- )
+(ert-deftest icalendar-tests--decode-isodatetime ()
+ "Test `icalendar--decode-isodatetime'."
+ (should (equal (icalendar-test--format "20040917T050910-02:00")
+ "2004-09-17T03:09:10+0000"))
+ (let ((orig (icalendar-test--format "20040917T050910")))
+ (unwind-protect
+ (let ((zone "XXX-02"))
+ (should (equal (icalendar-test--format "20040917T050910" nil zone)
+ "2004-09-17T03:09:10+0000"))
+ (should (equal (icalendar-test--format "20040917T0509" nil zone)
+ "2004-09-17T03:09:00+0000"))
+ (should (equal (icalendar-test--format "20040917" nil zone)
+ "2004-09-16T22:00:00+0000"))
+ (should (equal (icalendar-test--format "20040917T050910" 1 zone)
+ "2004-09-18T03:09:10+0000"))
+ (should (equal (icalendar-test--format "20040917T050910" 30 zone)
+ "2004-10-17T03:09:10+0000")))
+ (should (equal orig (icalendar-test--format "20040917T050910")))))
+ (should (equal (icalendar-test--format "20040917T050910Z")
+ "2004-09-17T05:09:10+0000"))
+ (should (equal (icalendar-test--format "20040917T050910" -1 0)
+ "2004-09-16T05:09:10+0000"))
+ (should (equal (icalendar-test--format "20040917T050910" nil -3600)
+ "2004-09-17T06:09:10+0000")))
(provide 'icalendar-tests)
;;; icalendar-tests.el ends here
diff --git a/test/lisp/calendar/iso8601-tests.el b/test/lisp/calendar/iso8601-tests.el
new file mode 100644
index 00000000000..f64c498c027
--- /dev/null
+++ b/test/lisp/calendar/iso8601-tests.el
@@ -0,0 +1,354 @@
+;;; iso8601-tests.el --- tests for calendar/iso8601.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 'iso8601)
+
+(ert-deftest test-iso8601-date-years ()
+ (should (equal (iso8601-parse-date "1985")
+ '(nil nil nil nil nil 1985 nil -1 nil)))
+ (should (equal (iso8601-parse-date "-0003")
+ '(nil nil nil nil nil -3 nil -1 nil)))
+ (should (equal (iso8601-parse-date "+1985")
+ '(nil nil nil nil nil 1985 nil -1 nil))))
+
+(ert-deftest test-iso8601-date-dates ()
+ (should (equal (iso8601-parse-date "1985-03-14")
+ '(nil nil nil 14 3 1985 nil -1 nil)))
+ (should (equal (iso8601-parse-date "19850314")
+ '(nil nil nil 14 3 1985 nil -1 nil)))
+ (should (equal (iso8601-parse-date "1985-02")
+ '(nil nil nil nil 2 1985 nil -1 nil))))
+
+(ert-deftest test-iso8601-date-obsolete ()
+ (should (equal (iso8601-parse-date "--02-01")
+ '(nil nil nil 1 2 nil nil -1 nil)))
+ (should (equal (iso8601-parse-date "--0201")
+ '(nil nil nil 1 2 nil nil -1 nil))))
+
+(ert-deftest test-iso8601-date-obsolete-2000 ()
+ ;; These are forms in 5.2.1.3 of the 2000 version of the standard,
+ ;; e) and f).
+ (should (equal (iso8601-parse-date "--12")
+ '(nil nil nil nil 12 nil nil -1 nil)))
+ (should (equal (iso8601-parse "--12T14")
+ '(0 0 14 nil 12 nil nil -1 nil)))
+ (should (equal (iso8601-parse-date "---12")
+ '(nil nil nil 12 nil nil nil -1 nil)))
+ (should (equal (iso8601-parse "---12T14:10:12")
+ '(12 10 14 12 nil nil nil -1 nil))))
+
+(ert-deftest test-iso8601-date-weeks ()
+ (should (equal (iso8601-parse-date "2008W39-6")
+ '(nil nil nil 27 9 2008 nil -1 nil)))
+ (should (equal (iso8601-parse-date "2009W01-1")
+ '(nil nil nil 29 12 2008 nil -1 nil)))
+ (should (equal (iso8601-parse-date "2009W53-7")
+ '(nil nil nil 3 1 2010 nil -1 nil))))
+
+(ert-deftest test-iso8601-date-ordinals ()
+ (should (equal (iso8601-parse-date "1981-095")
+ '(nil nil nil 5 4 1981 nil -1 nil))))
+
+(ert-deftest test-iso8601-time ()
+ (should (equal (iso8601-parse-time "13:47:30")
+ '(30 47 13 nil nil nil nil -1 nil)))
+ (should (equal (iso8601-parse-time "134730")
+ '(30 47 13 nil nil nil nil -1 nil)))
+ (should (equal (iso8601-parse-time "1347")
+ '(0 47 13 nil nil nil nil -1 nil))))
+
+(ert-deftest test-iso8601-combined ()
+ (should (equal (iso8601-parse "2008-03-02T13:47:30")
+ '(30 47 13 2 3 2008 nil -1 nil)))
+ (should (equal (iso8601-parse "2008-03-02T13:47:30Z")
+ '(30 47 13 2 3 2008 nil nil 0)))
+ (should (equal (iso8601-parse "2008-03-02T13:47:30+01:00")
+ '(30 47 13 2 3 2008 nil -1 3600)))
+ (should (equal (iso8601-parse "2008-03-02T13:47:30-01")
+ '(30 47 13 2 3 2008 nil -1 -3600))))
+
+(ert-deftest test-iso8601-duration ()
+ (should (equal (iso8601-parse-duration "P3Y6M4DT12H30M5S")
+ '(5 30 12 4 6 3 nil -1 nil)))
+ (should (equal (iso8601-parse-duration "P1M")
+ '(0 0 0 0 1 0 nil -1 nil)))
+ (should (equal (iso8601-parse-duration "PT1M")
+ '(0 1 0 0 0 0 nil -1 nil)))
+ (should (equal (iso8601-parse-duration "P0003-06-04T12:30:05")
+ '(5 30 12 4 6 3 nil -1 nil))))
+
+(ert-deftest test-iso8601-invalid ()
+ (should-not (iso8601-valid-p " 2008-03-02T13:47:30-01"))
+ (should-not (iso8601-valid-p "2008-03-02T13:47:30-01:200"))
+ (should-not (iso8601-valid-p "2008-03-02T13:47:30-01 "))
+ (should-not (iso8601-valid-p "2008-03-02 T 13:47:30-01 "))
+ (should-not (iso8601-valid-p "20008-03-02T13:47:30-01")))
+
+(ert-deftest test-iso8601-intervals ()
+ (should (equal
+ (iso8601-parse-interval "2007-03-01T13:00:00Z/2008-05-11T15:30:00Z")
+ '((0 0 13 1 3 2007 nil nil 0)
+ (0 30 15 11 5 2008 nil nil 0)
+ ;; Hm... can't really use decode-time for time differences...
+ (0 30 2 14 3 1971 0 nil 0))))
+ (should (equal (iso8601-parse-interval "2007-03-01T13:00:00Z/P1Y2M10DT2H30M")
+ '((0 0 13 1 3 2007 nil nil 0)
+ (0 30 15 11 5 2008 nil nil 0)
+ (0 30 2 10 2 1 nil -1 nil))))
+ (should (equal (iso8601-parse-interval "P1Y2M10DT2H30M/2008-05-11T15:30:00Z")
+ '((0 0 13 1 3 2007 nil nil 0)
+ (0 30 15 11 5 2008 nil nil 0)
+ (0 30 2 10 2 1 nil -1 nil)))))
+
+(ert-deftest standard-test-dates ()
+ (should (equal (iso8601-parse-date "19850412")
+ '(nil nil nil 12 4 1985 nil -1 nil)))
+ (should (equal (iso8601-parse-date "1985-04-12")
+ '(nil nil nil 12 4 1985 nil -1 nil)))
+
+ (should (equal (iso8601-parse-date "1985102")
+ '(nil nil nil 12 4 1985 nil -1 nil)))
+ (should (equal (iso8601-parse-date "1985-102")
+ '(nil nil nil 12 4 1985 nil -1 nil)))
+
+ (should (equal (iso8601-parse-date "1985W155")
+ '(nil nil nil 12 4 1985 nil -1 nil)))
+ (should (equal (iso8601-parse-date "1985-W15-5")
+ '(nil nil nil 12 4 1985 nil -1 nil)))
+
+ (should (equal (iso8601-parse-date "1985W15")
+ '(nil nil nil 7 4 1985 nil -1 nil)))
+ (should (equal (iso8601-parse-date "1985-W15")
+ '(nil nil nil 7 4 1985 nil -1 nil)))
+
+ (should (equal (iso8601-parse-date "1985-04")
+ '(nil nil nil nil 4 1985 nil -1 nil)))
+
+ (should (equal (iso8601-parse-date "1985")
+ '(nil nil nil nil nil 1985 nil -1 nil)))
+
+ (should (equal (iso8601-parse-date "+1985-04-12")
+ '(nil nil nil 12 4 1985 nil -1 nil)))
+ (should (equal (iso8601-parse-date "+19850412")
+ '(nil nil nil 12 4 1985 nil -1 nil))))
+
+(ert-deftest standard-test-time-of-day-local-time ()
+ (should (equal (iso8601-parse-time "152746")
+ '(46 27 15 nil nil nil nil -1 nil)))
+ (should (equal (iso8601-parse-time "15:27:46")
+ '(46 27 15 nil nil nil nil -1 nil)))
+
+ (should (equal (iso8601-parse-time "1528")
+ '(0 28 15 nil nil nil nil -1 nil)))
+ (should (equal (iso8601-parse-time "15:28")
+ '(0 28 15 nil nil nil nil -1 nil)))
+
+ (should (equal (iso8601-parse-time "15")
+ '(0 0 15 nil nil nil nil -1 nil))))
+
+(ert-deftest standard-test-time-of-day-fractions ()
+ (should (equal (iso8601-parse-time "152735,5" t)
+ '((355 . 10) 27 15 nil nil nil nil -1 nil)))
+ (should (equal (iso8601-parse-time "15:27:35,5" t)
+ '((355 . 10) 27 15 nil nil nil nil -1 nil)))
+
+ (should (equal (iso8601-parse-time "2320,5" t)
+ '(30 20 23 nil nil nil nil -1 nil)))
+ (should (equal (iso8601-parse-time "23:20,8" t)
+ '(48 20 23 nil nil nil nil -1 nil)))
+
+ (should (equal (iso8601-parse-time "23,3" t)
+ '(0 18 23 nil nil nil nil -1 nil))))
+
+(ert-deftest nonstandard-test-time-of-day-decimals ()
+ (should (equal (iso8601-parse-time "15:27:35.123" t)
+ '((35123 . 1000) 27 15 nil nil nil nil -1 nil)))
+ (should (equal (iso8601-parse-time "15:27:35.123456789" t)
+ '((35123456789 . 1000000000) 27 15 nil nil nil nil -1 nil)))
+ (should (equal (iso8601-parse-time "15:27:35.012345678" t)
+ '((35012345678 . 1000000000) 27 15 nil nil nil nil -1 nil)))
+ (should (equal (iso8601-parse-time "15:27:35.00001" t)
+ '((3500001 . 100000) 27 15 nil nil nil nil -1 nil)))
+ (should (equal (iso8601-parse-time "15:27:35.0000100" t)
+ '((3500001 . 100000) 27 15 nil nil nil nil -1 nil)))
+ (should (equal (iso8601-parse-time "15:27:35.0" t)
+ '(35 27 15 nil nil nil nil -1 nil))))
+
+(ert-deftest standard-test-time-of-day-beginning-of-day ()
+ (should (equal (iso8601-parse-time "000000")
+ '(0 0 0 nil nil nil nil -1 nil)))
+ (should (equal (iso8601-parse-time "00:00:00")
+ '(0 0 0 nil nil nil nil -1 nil)))
+
+ (should (equal (iso8601-parse-time "0000")
+ '(0 0 0 nil nil nil nil -1 nil)))
+ (should (equal (iso8601-parse-time "00:00")
+ '(0 0 0 nil nil nil nil -1 nil))))
+
+(ert-deftest standard-test-time-of-day-utc ()
+ (should (equal (iso8601-parse-time "232030Z")
+ '(30 20 23 nil nil nil nil nil 0)))
+ (should (equal (iso8601-parse-time "23:20:30Z")
+ '(30 20 23 nil nil nil nil nil 0)))
+
+ (should (equal (iso8601-parse-time "2320Z")
+ '(0 20 23 nil nil nil nil nil 0)))
+ (should (equal (iso8601-parse-time "23:20Z")
+ '(0 20 23 nil nil nil nil nil 0)))
+
+ (should (equal (iso8601-parse-time "23Z")
+ '(0 0 23 nil nil nil nil nil 0))))
+
+
+(ert-deftest standard-test-time-of-day-zone ()
+ (should (equal (iso8601-parse-time "152746+0100")
+ '(46 27 15 nil nil nil nil -1 3600)))
+ (should (equal (iso8601-parse-time "15:27:46+0100")
+ '(46 27 15 nil nil nil nil -1 3600)))
+
+ (should (equal (iso8601-parse-time "152746+01")
+ '(46 27 15 nil nil nil nil -1 3600)))
+ (should (equal (iso8601-parse-time "15:27:46+01")
+ '(46 27 15 nil nil nil nil -1 3600)))
+
+ (should (equal (iso8601-parse-time "152746-0500")
+ '(46 27 15 nil nil nil nil -1 -18000)))
+ (should (equal (iso8601-parse-time "15:27:46-0500")
+ '(46 27 15 nil nil nil nil -1 -18000)))
+
+ (should (equal (iso8601-parse-time "152746-05")
+ '(46 27 15 nil nil nil nil -1 -18000)))
+ (should (equal (iso8601-parse-time "15:27:46-05")
+ '(46 27 15 nil nil nil nil -1 -18000))))
+
+
+(defun test-iso8601-format-time-string-zone-round-trip (offset-minutes z-format)
+ "Pass OFFSET-MINUTES to format-time-string with Z-FORMAT, a %z variation,
+and then to iso8601-parse-zone. The result should be the original offset."
+ (let* ((offset-seconds (* 60 offset-minutes))
+ (zone-string (format-time-string z-format 0 offset-seconds))
+ (offset-rt
+ (condition-case nil
+ (iso8601-parse-zone zone-string)
+ (wrong-type-argument (format "(failed to parse %S)" zone-string))))
+ ;; compare strings that contain enough info to debug failures
+ (success (format "%s(%s) -> %S -> %s"
+ z-format offset-minutes zone-string offset-minutes))
+ (actual (format "%s(%s) -> %S -> %s"
+ z-format offset-minutes zone-string offset-rt)))
+ (should (equal success actual))))
+
+(ert-deftest iso8601-format-time-string-zone-round-trip ()
+ "Round trip zone offsets through format-time-string and iso8601-parse-zone.
+Passing a time zone created by format-time-string %z to
+iso8601-parse-zone should yield the original offset."
+ (dolist (offset-minutes
+ (list
+ ;; compare hours (1- and 2-digit), minutes, both, neither
+ (* 5 60) (* 11 60) 5 11 (+ (* 5 60) 30) (+ (* 11 60) 30) 0
+ ;; do negative values, too
+ (* -5 60) (* -11 60) -5 -11 (- (* -5 60) 30) (- (* -11 60) 30)))
+ (dolist (z-format '("%z" "%:z" "%:::z"))
+ (test-iso8601-format-time-string-zone-round-trip
+ offset-minutes z-format))))
+
+(ert-deftest standard-test-date-and-time-of-day ()
+ (should (equal (iso8601-parse "19850412T101530")
+ '(30 15 10 12 4 1985 nil -1 nil)))
+ (should (equal (iso8601-parse "1985-04-12T10:15:30")
+ '(30 15 10 12 4 1985 nil -1 nil)))
+
+ (should (equal (iso8601-parse "1985102T235030Z")
+ '(30 50 23 12 4 1985 nil nil 0)))
+ (should (equal (iso8601-parse "1985-102T23:50:30Z")
+ '(30 50 23 12 4 1985 nil nil 0)))
+
+ (should (equal (iso8601-parse "1985W155T235030")
+ '(30 50 23 12 4 1985 nil -1 nil)))
+ (should (equal (iso8601-parse "1985-W155T23:50:30")
+ '(30 50 23 12 4 1985 nil -1 nil))))
+
+(ert-deftest standard-test-interval ()
+ ;; A time interval starting at 20 minutes and 50 seconds past 23
+ ;; hours on 12 April 1985 and ending at 30 minutes past 10 hours on
+ ;; 25 June 1985.
+ (should (equal (iso8601-parse-interval "19850412T232050Z/19850625T103000Z")
+ '((50 20 23 12 4 1985 nil nil 0)
+ (0 30 10 25 6 1985 nil nil 0)
+ (10 9 11 15 3 1970 0 nil 0))))
+ (should (equal (iso8601-parse-interval
+ "1985-04-12T23:20:50Z/1985-06-25T10:30:00Z")
+ '((50 20 23 12 4 1985 nil nil 0)
+ (0 30 10 25 6 1985 nil nil 0)
+ (10 9 11 15 3 1970 0 nil 0))))
+
+ ;; A time interval starting at 12 April 1985 and ending on 25 June
+ ;; 1985.
+
+ ;; This example doesn't seem valid according to the standard.
+ ;; "0625" is unambiguous, and means "the year 625". Weird.
+ ;; (should (equal (iso8601-parse-interval "19850412/0625")
+ ;; '((nil nil nil 12 4 1985 nil -1 nil)
+ ;; (nil nil nil nil nil 625 nil -1 nil)
+ ;; (0 17 0 22 9 609 5 nil 0))))
+
+ ;; A time interval of 2 years, 10 months, 15 days, 10 hours, 20
+ ;; minutes and 30 seconds.
+ (should (equal (iso8601-parse-duration "P2Y10M15DT10H20M30S")
+ '(30 20 10 15 10 2 nil -1 nil)))
+
+ (should (equal (iso8601-parse-duration "P00021015T102030")
+ '(30 20 10 15 10 2 nil -1 nil)))
+ (should (equal (iso8601-parse-duration "P0002-10-15T10:20:30")
+ '(30 20 10 15 10 2 nil -1 nil)))
+
+ ;; A time interval of 1 year and 6 months.
+ (should (equal (iso8601-parse-duration "P1Y6M")
+ '(0 0 0 0 6 1 nil -1 nil)))
+ (should (equal (iso8601-parse-duration "P0001-06")
+ '(nil nil nil nil 6 1 nil -1 nil)))
+
+ ;; A time interval of seventy-two hours.
+ (should (equal (iso8601-parse-duration "PT72H")
+ '(0 0 72 0 0 0 nil -1 nil)))
+
+ ;; Defined by start and duration
+ ;; A time interval of 1 year, 2 months, 15 days and 12 hours,
+ ;; beginning on 12 April 1985 at 20 minutes past 23 hours.
+ (should (equal (iso8601-parse-interval "19850412T232000/P1Y2M15DT12H")
+ '((0 20 23 12 4 1985 nil -1 nil)
+ (0 20 11 28 6 1986 nil -1 nil)
+ (0 0 12 15 2 1 nil -1 nil))))
+ (should (equal (iso8601-parse-interval "1985-04-12T23:20:00/P1Y2M15DT12H")
+ '((0 20 23 12 4 1985 nil -1 nil)
+ (0 20 11 28 6 1986 nil -1 nil)
+ (0 0 12 15 2 1 nil -1 nil))))
+
+ ;; Defined by duration and end
+ ;; A time interval of 1 year, 2 months, 15 days and 12 hours, ending
+ ;; on 12 April 1985 at 20 minutes past 23 hour.
+ (should (equal (iso8601-parse-interval "P1Y2M15DT12H/19850412T232000")
+ '((0 20 11 28 1 1984 nil -1 nil)
+ (0 20 23 12 4 1985 nil -1 nil)
+ (0 0 12 15 2 1 nil -1 nil)))))
+
+;;; iso8601-tests.el ends here
diff --git a/test/lisp/calendar/lunar-tests.el b/test/lisp/calendar/lunar-tests.el
new file mode 100644
index 00000000000..846a749eb5f
--- /dev/null
+++ b/test/lisp/calendar/lunar-tests.el
@@ -0,0 +1,73 @@
+;;; lunar-tests.el --- tests for calendar/lunar.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/>.
+
+;;; Code:
+
+(require 'ert)
+(require 'lunar)
+
+(defmacro with-lunar-test (&rest body)
+ `(let ((calendar-latitude 40.1)
+ (calendar-longitude -88.2)
+ (calendar-location-name "Paris")
+ (calendar-time-zone 0)
+ (calendar-standard-time-zone-name "UTC")
+ ;; Make sure daylight saving is disabled to avoid interference
+ ;; from the system settings (see bug#45818).
+ (calendar-daylight-savings-starts nil)
+ (calendar-time-display-form '(24-hours ":" minutes)))
+ ,@body))
+
+(ert-deftest lunar-test-phase ()
+ (with-lunar-test
+ (should (equal (lunar-phase 1)
+ '((1 8 1900) "05:40" 1 "")))))
+
+(ert-deftest lunar-test-eclipse-check ()
+ (with-lunar-test
+ (should (equal (eclipse-check 1 1) "** Eclipse **"))))
+
+(ert-deftest lunar-test-phase-list ()
+ (with-lunar-test
+ (should (equal (lunar-phase-list 3 1871)
+ '(((3 21 1871) "04:03" 0 "")
+ ((3 29 1871) "06:46" 1 "** Eclipse **")
+ ((4 5 1871) "14:20" 2 "")
+ ((4 12 1871) "05:57" 3 "** Eclipse possible **")
+ ((4 19 1871) "19:06" 0 "")
+ ((4 27 1871) "23:49" 1 "")
+ ((5 4 1871) "22:57" 2 "")
+ ((5 11 1871) "14:29" 3 "")
+ ((5 19 1871) "10:46" 0 "")
+ ((5 27 1871) "13:02" 1 ""))))))
+
+(ert-deftest lunar-test-new-moon-time ()
+ (with-lunar-test
+ (should (= (round (lunar-new-moon-time 1))
+ 2451580))))
+
+(ert-deftest lunar-test-new-moon-on-or-after ()
+ (with-lunar-test
+ (should (= (round (lunar-new-moon-on-or-after (calendar-absolute-from-gregorian '(5 5 1818))))
+ 664525))))
+
+(provide 'lunar-tests)
+;;; lunar-tests.el ends here
diff --git a/test/lisp/calendar/parse-time-tests.el b/test/lisp/calendar/parse-time-tests.el
index 0ad0b36438f..3fd53c6c1eb 100644
--- a/test/lisp/calendar/parse-time-tests.el
+++ b/test/lisp/calendar/parse-time-tests.el
@@ -1,6 +1,6 @@
-;; parse-time-tests.el --- Test suite for parse-time.el
+;;; parse-time-tests.el --- Test suite for parse-time.el -*- lexical-binding:t -*-
-;; Copyright (C) 2016-2017 Free Software Foundation, Inc.
+;; Copyright (C) 2016-2022 Free Software Foundation, Inc.
;; Author: Lars Ingebrigtsen <larsi@gnus.org>
@@ -28,35 +28,51 @@
(ert-deftest parse-time-tests ()
(should (equal (parse-time-string "Mon, 22 Feb 2016 19:35:42 +0100")
- '(42 35 19 22 2 2016 1 nil 3600)))
+ '(42 35 19 22 2 2016 1 -1 3600)))
(should (equal (parse-time-string "22 Feb 2016 19:35:42 +0100")
- '(42 35 19 22 2 2016 nil nil 3600)))
+ '(42 35 19 22 2 2016 nil -1 3600)))
(should (equal (parse-time-string "22 Feb 2016 +0100")
- '(nil nil nil 22 2 2016 nil nil 3600)))
+ '(nil nil nil 22 2 2016 nil -1 3600)))
(should (equal (parse-time-string "Mon, 22 Feb 16 19:35:42 +0100")
- '(42 35 19 22 2 2016 1 nil 3600)))
+ '(42 35 19 22 2 2016 1 -1 3600)))
(should (equal (parse-time-string "Mon, 22 February 2016 19:35:42 +0100")
- '(42 35 19 22 2 2016 1 nil 3600)))
+ '(42 35 19 22 2 2016 1 -1 3600)))
(should (equal (parse-time-string "Mon, 22 feb 2016 19:35:42 +0100")
- '(42 35 19 22 2 2016 1 nil 3600)))
+ '(42 35 19 22 2 2016 1 -1 3600)))
(should (equal (parse-time-string "Monday, 22 february 2016 19:35:42 +0100")
- '(42 35 19 22 2 2016 1 nil 3600)))
- (should (equal (parse-time-string "Monday, 22 february 2016 19:35:42 PDT")
- '(42 35 19 22 2 2016 1 t -25200)))
- (should (equal (parse-iso8601-time-string "1998-09-12T12:21:54-0200")
- '(13818 33666)))
- (should (equal (parse-iso8601-time-string "1998-09-12T12:21:54-0230")
- '(13818 35466)))
- (should (equal (parse-iso8601-time-string "1998-09-12T12:21:54-02:00")
- '(13818 33666)))
- (should (equal (parse-iso8601-time-string "1998-09-12T12:21:54-02")
- '(13818 33666)))
- (should (equal (parse-iso8601-time-string "1998-09-12T12:21:54+0230")
- '(13818 17466)))
- (should (equal (parse-iso8601-time-string "1998-09-12T12:21:54+02")
- '(13818 19266)))
- (should (equal (parse-iso8601-time-string "1998-09-12T12:21:54Z")
- '(13818 26466)))
+ '(42 35 19 22 2 2016 1 -1 3600)))
+ (should (equal (parse-time-string "Monday, 22 february 2016 19:35:42 PST")
+ '(42 35 19 22 2 2016 1 nil -28800)))
+ (should (equal (parse-time-string "Friday, 21 Sep 2018 13:47:58 PDT")
+ '(58 47 13 21 9 2018 5 t -25200)))
+ (should (equal (format-time-string
+ "%Y-%m-%d %H:%M:%S"
+ (parse-iso8601-time-string "1998-09-12T12:21:54-0200") t)
+ "1998-09-12 14:21:54"))
+ (should (equal (format-time-string
+ "%Y-%m-%d %H:%M:%S"
+ (parse-iso8601-time-string "1998-09-12T12:21:54-0230") t)
+ "1998-09-12 14:51:54"))
+ (should (equal (format-time-string
+ "%Y-%m-%d %H:%M:%S"
+ (parse-iso8601-time-string "1998-09-12T12:21:54-02:00") t)
+ "1998-09-12 14:21:54"))
+ (should (equal (format-time-string
+ "%Y-%m-%d %H:%M:%S"
+ (parse-iso8601-time-string "1998-09-12T12:21:54-02") t)
+ "1998-09-12 14:21:54"))
+ (should (equal (format-time-string
+ "%Y-%m-%d %H:%M:%S"
+ (parse-iso8601-time-string "1998-09-12T12:21:54+0230") t)
+ "1998-09-12 09:51:54"))
+ (should (equal (format-time-string
+ "%Y-%m-%d %H:%M:%S"
+ (parse-iso8601-time-string "1998-09-12T12:21:54+02") t)
+ "1998-09-12 10:21:54"))
+ (should (equal (format-time-string
+ "%Y-%m-%d %H:%M:%S"
+ (parse-iso8601-time-string "1998-09-12T12:21:54Z") t)
+ "1998-09-12 12:21:54"))
(should (equal (parse-iso8601-time-string "1998-09-12T12:21:54")
(encode-time 54 21 12 12 9 1998))))
diff --git a/test/lisp/calendar/solar-tests.el b/test/lisp/calendar/solar-tests.el
new file mode 100644
index 00000000000..9f79fed7c7b
--- /dev/null
+++ b/test/lisp/calendar/solar-tests.el
@@ -0,0 +1,48 @@
+;;; solar-tests.el --- tests for solar.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/>.
+
+;;; Code:
+
+(require 'ert)
+(require 'solar)
+
+(ert-deftest solar-sunrise-sunset ()
+ ;; Bug#44237: wrong sunrise time on Dec 30 and 31, 2020 for Jaipur.
+ (let ((calendar-latitude 26.9)
+ (calendar-longitude 75.8)
+ (calendar-time-zone +330)
+ (calendar-standard-time-zone-name "IST")
+ ;; Make sure our clockwork isn't confused by daylight saving rules
+ ;; in effect for any other time zone (bug#45818).
+ (calendar-daylight-savings-starts nil)
+ (epsilon (/ 60.0))) ; Minute accuracy is good enough.
+ (let* ((sunrise-sunset (solar-sunrise-sunset '(12 30 2020)))
+ (sunrise (car (nth 0 sunrise-sunset)))
+ (sunset (car (nth 1 sunrise-sunset))))
+ (should (< (abs (- sunrise 7.27)) epsilon))
+ (should (< (abs (- sunset 17.72)) epsilon)))
+ (let* ((sunrise-sunset (solar-sunrise-sunset '(12 31 2020)))
+ (sunrise (car (nth 0 sunrise-sunset)))
+ (sunset (car (nth 1 sunrise-sunset))))
+ (should (< (abs (- sunrise 7.28)) epsilon))
+ (should (< (abs (- sunset 17.72)) epsilon)))))
+
+(provide 'solar-tests)
+
+;;; solar-tests.el ends here
diff --git a/test/lisp/calendar/time-date-tests.el b/test/lisp/calendar/time-date-tests.el
new file mode 100644
index 00000000000..fd4d5ac8a1b
--- /dev/null
+++ b/test/lisp/calendar/time-date-tests.el
@@ -0,0 +1,216 @@
+;;; time-date-tests.el --- tests for calendar/time-date.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 'time-date)
+
+(ert-deftest test-obsolete-with-decoded-time-value ()
+ (with-suppressed-warnings ((obsolete with-decoded-time-value))
+ (with-decoded-time-value ((high low micro pico type '(1 2 3 4 5 6 8 8)))
+ (should (equal (list high low micro pico type) '(1 2 3 4 3))))))
+
+(ert-deftest test-obsolete-encode-time-value ()
+ (should (equal (with-suppressed-warnings ((obsolete encode-time-value))
+ (encode-time-value 1 2 3 4 0))
+ '(1 . 2)))
+ (should (equal (with-suppressed-warnings ((obsolete encode-time-value))
+ (encode-time-value 1 2 3 4 1))
+ '(1 2)))
+ (should (equal (with-suppressed-warnings ((obsolete encode-time-value))
+ (encode-time-value 1 2 3 4 2))
+ '(1 2 3)))
+ (should (equal (with-suppressed-warnings ((obsolete encode-time-value))
+ (encode-time-value 1 2 3 4 3))
+ '(1 2 3 4))))
+
+(ert-deftest test-date-to-time ()
+ (should (equal (format-time-string "%F %T" (date-to-time "2021-12-04"))
+ "2021-12-04 00:00:00")))
+
+(ert-deftest test-days-between ()
+ (should (equal (days-between "2021-10-22" "2020-09-29") 388)))
+
+(ert-deftest test-leap-year ()
+ (should-not (date-leap-year-p 1999))
+ (should-not (date-leap-year-p 1900))
+ (should (date-leap-year-p 2000))
+ (should (date-leap-year-p 2004)))
+
+(ert-deftest test-days-to-time ()
+ (should (time-equal-p (days-to-time 0) '(0 0)))
+ (should (time-equal-p (days-to-time 1) '(1 20864)))
+ (should (time-equal-p (days-to-time 999) '(1317 2688)))
+ (should (time-equal-p (days-to-time 0.0) '(0 0 0 0)))
+ (should (time-equal-p (days-to-time 0.5) '(0 43200 0 0)))
+ (should (time-equal-p (days-to-time 1.0) '(1 20864 0 0)))
+ (should (time-equal-p (days-to-time 999.0) '(1317 2688 0 0))))
+
+(ert-deftest test-seconds-to-string ()
+ (should (equal (seconds-to-string 0) "0s"))
+ (should (equal (seconds-to-string 9) "9.00s"))
+ (should (equal (seconds-to-string 99) "99.00s"))
+ (should (equal (seconds-to-string 999) "16.65m"))
+ (should (equal (seconds-to-string 9999) "2.78h"))
+ (should (equal (seconds-to-string 99999) "27.78h"))
+ (should (equal (seconds-to-string 999999) "11.57d"))
+ (should (equal (seconds-to-string 9999999) "115.74d"))
+ (should (equal (seconds-to-string 99999999) "3.17y"))
+ (should (equal (seconds-to-string 999999999) "31.69y")))
+
+(ert-deftest test-days-in-month ()
+ (should (= (date-days-in-month 2004 2) 29))
+ (should (= (date-days-in-month 2004 3) 31))
+ (should (= (date-days-in-month 2019 2) 28))
+ (should (= (date-days-in-month 2020 12) 31))
+ (should-not (= (date-days-in-month 1900 3) 28))
+ (should-error (date-days-in-month 2020 0))
+ (should-error (date-days-in-month 2020 15))
+ (should-error (date-days-in-month 2020 'foo)))
+
+(ert-deftest test-format-seconds ()
+ (should (equal (format-seconds "%y %d %h %m %s %%" 0) "0 0 0 0 0 %"))
+ (should (equal (format-seconds "%y %d %h %m %s %%" 9999999) "0 115 17 46 39 %"))
+ (should (equal (format-seconds "%y %d %h %m %z %s %%" 1) "1 %"))
+ (should (equal (format-seconds "%mm %ss" 66) "1m 6s"))
+ (should (equal (format-seconds "%mm %5ss" 66) "1m 6s"))
+ (should (equal (format-seconds "%mm %.5ss" 66.4) "1m 00006s"))
+
+ (should (equal (format-seconds "%mm %,1ss" 66.4) "1m 6.4s"))
+ (should (equal (format-seconds "%mm %5,1ss" 66.4) "1m 6.4s"))
+ (should (equal (format-seconds "%mm %.5,1ss" 66.4) "1m 006.4s"))
+
+ (should (equal (format-seconds "%hh %z%x%mm %ss" (* 60 2)) "2m"))
+ (should (equal (format-seconds "%hh %z%mm %ss" (* 60 2)) "2m 0s"))
+ (should (equal (format-seconds "%hh %x%mm %ss" (* 60 2)) "0h 2m"))
+ (should (equal (format-seconds "%hh %x%mm %ss" 0) "0h 0m 0s")))
+
+(ert-deftest test-ordinal ()
+ (should (equal (date-ordinal-to-time 2008 271)
+ '(nil nil nil 27 9 2008 nil nil nil)))
+ (should (equal (date-ordinal-to-time 2008 1)
+ '(nil nil nil 1 1 2008 nil nil nil)))
+ (should (equal (date-ordinal-to-time 2008 32)
+ '(nil nil nil 1 2 2008 nil nil nil)))
+ (should (equal (date-ordinal-to-time 1981 095)
+ '(nil nil nil 5 4 1981 nil nil nil))))
+
+(cl-defmethod mdec (&key second minute hour
+ day month year
+ dst zone)
+ (list second minute hour day month year nil dst zone))
+
+(ert-deftest test-decoded-add ()
+ (let ((time '(12 15 16 8 7 2019 1 t 7200)))
+ (should (equal (decoded-time-add time (mdec :year 1))
+ '(12 15 16 8 7 2020 1 t 7200)))
+
+ (should (equal (decoded-time-add time (mdec :year -2))
+ '(12 15 16 8 7 2017 1 t 7200)))
+
+ (should (equal (decoded-time-add time (mdec :month 1))
+ '(12 15 16 8 8 2019 1 t 7200)))
+
+ (should (equal (decoded-time-add time (mdec :month 10))
+ '(12 15 16 8 5 2020 1 t 7200)))
+
+ (should (equal (decoded-time-add time (mdec :day 1))
+ '(12 15 16 9 7 2019 1 t 7200)))
+
+ (should (equal (decoded-time-add time (mdec :day -1))
+ '(12 15 16 7 7 2019 1 t 7200)))
+
+ (should (equal (decoded-time-add time (mdec :day 30))
+ '(12 15 16 7 8 2019 1 t 7200)))
+
+ (should (equal (decoded-time-add time (mdec :day -365))
+ '(12 15 16 8 7 2018 1 t 7200)))
+
+ (should (equal (decoded-time-add time (mdec :day 365))
+ '(12 15 16 7 7 2020 1 t 7200)))
+
+ ;; 2020 is a leap year.
+ (should (equal (decoded-time-add time (mdec :day 366))
+ '(12 15 16 8 7 2020 1 t 7200)))
+
+ (should (equal (decoded-time-add time (mdec :second 1))
+ '(13 15 16 8 7 2019 1 t 7200)))
+
+ (should (equal (decoded-time-add time (mdec :second -1))
+ '(11 15 16 8 7 2019 1 t 7200)))
+
+ (should (equal (decoded-time-add time (mdec :second 61))
+ '(13 16 16 8 7 2019 1 t 7200)))
+
+ (should (equal (decoded-time-add time (mdec :hour 1 :minute 2 :second 3))
+ '(15 17 17 8 7 2019 1 t 7200)))
+
+ (should (equal (decoded-time-add time (mdec :hour 24))
+ '(12 15 16 9 7 2019 1 t 7200)))
+ ))
+
+(ert-deftest test-decoded-add-zone ()
+ (let ((time '(12 15 16 8 7 2019 1 t 7200)))
+ (should (equal (decoded-time-add time (mdec :zone -3600))
+ '(12 15 15 8 7 2019 1 t 7200)))
+ (should (equal (decoded-time-add time (mdec :zone -7200))
+ '(12 15 14 8 7 2019 1 t 7200)))))
+
+(ert-deftest test-time-since ()
+ (should (time-equal-p 0 (time-since nil)))
+ (should (time-equal-p 1 (time-convert (time-since (time-subtract nil 1))
+ 'integer))))
+
+(ert-deftest test-time-decoded-period ()
+ (should (equal (decoded-time-period '(nil nil 1 nil nil nil nil nil nil))
+ 3600))
+
+ (should (equal (decoded-time-period '(1 0 0 0 0 0 nil nil nil)) 1))
+ (should (equal (decoded-time-period '(0 1 0 0 0 0 nil nil nil)) 60))
+ (should (equal (decoded-time-period '(0 0 1 0 0 0 nil nil nil)) 3600))
+ (should (equal (decoded-time-period '(0 0 0 1 0 0 nil nil nil)) 86400))
+ (should (equal (decoded-time-period '(0 0 0 0 1 0 nil nil nil)) 2592000))
+ (should (equal (decoded-time-period '(0 0 0 0 0 1 nil nil nil)) 31536000))
+ (should (equal (decoded-time-period '(1 2 3 4 5 6 nil nil nil)) 202532521))
+
+ (should (equal (decoded-time-period '((135 . 10) 0 0 0 0 0 nil nil nil))
+ 13.5)))
+
+(ert-deftest test-time-wrap-addition ()
+ (should (equal (decoded-time-add '(0 0 0 1 11 2008 nil nil nil)
+ (make-decoded-time :month 1))
+ '(0 0 0 1 12 2008 nil nil nil)))
+ (should (equal (decoded-time-add '(0 0 0 1 12 2008 nil nil nil)
+ (make-decoded-time :month 1))
+ '(0 0 0 1 1 2009 nil nil nil)))
+ (should (equal (decoded-time-add '(0 0 0 1 11 2008 nil nil nil)
+ (make-decoded-time :month 12))
+ '(0 0 0 1 11 2009 nil nil nil)))
+ (should (equal (decoded-time-add '(0 0 0 1 11 2008 nil nil nil)
+ (make-decoded-time :month 13))
+ '(0 0 0 1 12 2009 nil nil nil)))
+ (should (equal (decoded-time-add '(0 0 0 30 12 2008 nil nil nil)
+ (make-decoded-time :day 1))
+ '(0 0 0 31 12 2008 nil nil nil)))
+ (should (equal (decoded-time-add '(0 0 0 30 12 2008 nil nil nil)
+ (make-decoded-time :day 2))
+ '(0 0 0 1 1 2009 nil nil nil))))
+
+;;; time-date-tests.el ends here
diff --git a/test/lisp/calendar/todo-mode-resources/todo-test-1.todo b/test/lisp/calendar/todo-mode-resources/todo-test-1.todo
index 598d487cad9..2375772fbe7 100644
--- a/test/lisp/calendar/todo-mode-resources/todo-test-1.todo
+++ b/test/lisp/calendar/todo-mode-resources/todo-test-1.todo
@@ -1,8 +1,8 @@
-(("testcat1" . [2 0 2 1]) ("testcat2" . [3 0 1 1]) ("testcat3" . [0 0 0 0]))
+(("testcat1" . [2 0 2 1]) ("testcat2" . [3 0 1 1]) ("testcat3" . [0 0 0 0]) ("testcat4" . [1 0 0 0]))
--==-- testcat1
[May 29, 2017] testcat1 item3
- has more than one line
- to test item highlighting
+ has more than one line
+ to test item highlighting
[Jul 3, 2017] testcat1 item4
==--== DONE
@@ -18,3 +18,7 @@
--==-- testcat3
==--== DONE
+--==-- testcat4
+[Jan 1, 2020] testcat4 item1
+
+==--== DONE
diff --git a/test/lisp/calendar/todo-mode-tests.el b/test/lisp/calendar/todo-mode-tests.el
index 66ddbbcc964..95855d1e639 100644
--- a/test/lisp/calendar/todo-mode-tests.el
+++ b/test/lisp/calendar/todo-mode-tests.el
@@ -1,6 +1,6 @@
;;; todo-mode-tests.el --- tests for todo-mode.el -*- lexical-binding: t; -*-
-;; Copyright (C) 2017 Free Software Foundation, Inc.
+;; Copyright (C) 2017-2022 Free Software Foundation, Inc.
;; Author: Stephen Berman <stephen.berman@gmx.net>
;; Keywords: calendar
@@ -25,45 +25,36 @@
;;; Code:
(require 'ert)
+(require 'ert-x)
(require 'todo-mode)
-(defvar todo-test-data-dir
- (file-truename
- (expand-file-name "todo-mode-resources/"
- (file-name-directory (or load-file-name
- buffer-file-name))))
- "Base directory of todo-mode.el test data files.")
-
-(defvar todo-test-file-1 (expand-file-name "todo-test-1.todo"
- todo-test-data-dir)
+(defvar todo-test-file-1 (ert-resource-file "todo-test-1.todo")
"Todo mode test file.")
-(defvar todo-test-archive-1 (expand-file-name "todo-test-1.toda"
- todo-test-data-dir)
+(defvar todo-test-archive-1 (ert-resource-file "todo-test-1.toda")
"Todo Archive mode test file.")
(defmacro with-todo-test (&rest body)
- "Set up an isolated todo-mode test environment."
+ "Set up an isolated `todo-mode' test environment."
(declare (debug (body)))
- `(let* ((todo-test-home (make-temp-file "todo-test-home-" t))
- ;; Since we change HOME, clear this to avoid a conflict
- ;; e.g. if Emacs runs within the user's home directory.
- (abbreviated-home-dir nil)
- (process-environment (cons (format "HOME=%s" todo-test-home)
- process-environment))
- (todo-directory todo-test-data-dir)
- (todo-default-todo-file (todo-short-file-name
- (car (funcall todo-files-function)))))
- (unwind-protect
- (progn ,@body)
- ;; Restore pre-test-run state of test files.
- (dolist (f (directory-files todo-directory))
- (let ((buf (get-file-buffer f)))
- (when buf
- (with-current-buffer buf
- (restore-buffer-modified-p nil)
- (kill-buffer)))))
- (delete-directory todo-test-home t))))
+ `(ert-with-temp-directory todo-test-home
+ (let* (;; Since we change HOME, clear this to avoid a conflict
+ ;; e.g. if Emacs runs within the user's home directory.
+ (abbreviated-home-dir nil)
+ (process-environment (cons (format "HOME=%s" todo-test-home)
+ process-environment))
+ (todo-directory (ert-resource-directory))
+ (todo-default-todo-file (todo-short-file-name
+ (car (funcall todo-files-function)))))
+ (unwind-protect
+ (progn ,@body)
+ ;; Restore pre-test-run state of test files.
+ (dolist (f (directory-files todo-directory))
+ (let ((buf (get-file-buffer f)))
+ (when buf
+ (with-current-buffer buf
+ (restore-buffer-modified-p nil)
+ (kill-buffer)))))))))
(defun todo-test--show (num &optional archive)
"Display category NUM of test todo file.
@@ -384,7 +375,7 @@ priority and the done item should be the first done item."
(ert-deftest todo-test-move-item05 () ; bug#27609
"Test moving multiple todo and done items to another category.
Both types of item should be moved en bloc to the new category,
-and the the top todo item should have the provided priority and
+and the top todo item should have the provided priority and
the top done item should be the first done item."
(with-todo-test
(todo-test--show 1)
@@ -413,8 +404,15 @@ the top done item should be the first done item."
(should (todo-done-item-p))
(forward-line -1)
(should (looking-at todo-category-done))
- ;; Make sure marked items are no longer in first category.
- (todo-backward-category)
+ ;; Make sure marked items are no longer in first category. Since
+ ;; cat1 now contains no todo or done items but does have archived
+ ;; items, todo-backward-category would skip it by default, so
+ ;; prevent this. (FIXME: Without this let-binding,
+ ;; todo-backward-category selects the nonempty cat4 and this test
+ ;; fails as expected when run interactively but not in a batch
+ ;; run -- why?)
+ (let (todo-skip-archived-categories)
+ (todo-backward-category))
(should (eq (point-min) (point-max))) ; All todo items were moved.
;; This passes when run interactively but fails in a batch run:
;; the message is displayed but (current-message) evaluates to
@@ -461,7 +459,7 @@ the top done item should be the first done item."
todo-date-pattern
"\\( " diary-time-regexp "\\)?"
(regexp-quote todo-nondiary-end) "?")
- (line-end-position) t)
+ (pos-eol) t)
(forward-char)
(point)))
(start1 (save-excursion (funcall find-start)))
@@ -561,16 +559,17 @@ source file is different."
;; Headers in the todo file are still hidden.
(should (equal (overlay-get (todo-get-overlay 'header) 'display) "")))))
-(defun todo-test--insert-item (item &optional priority)
+(defun todo-test--insert-item (item &optional priority
+ _arg diary-type date-type time where)
"Insert string ITEM into current category with priority PRIORITY.
-Use defaults for all other item insertion parameters. This
-provides a noninteractive API for todo-insert-item for use in
-automatic testing."
+The remaining arguments (except _ARG, which is ignored) specify
+item insertion parameters. This provides a noninteractive API
+for todo-insert-item for use in automatic testing."
(cl-letf (((symbol-function 'read-from-minibuffer)
- (lambda (_prompt) item))
+ (lambda (_prompt &rest _) item))
((symbol-function 'read-number) ; For todo-set-item-priority
(lambda (_prompt &optional _default) (or priority 1))))
- (todo-insert-item--basic)))
+ (todo-insert-item--basic nil diary-type date-type time where)))
(ert-deftest todo-test-toggle-item-header07 () ; bug#27609
"Test display of hidden item header under todo-insert-item."
@@ -581,6 +580,359 @@ automatic testing."
(todo-test--insert-item item 1)
(should (equal (overlay-get (todo-get-overlay 'header) 'display) "")))))
+(defun todo-test--done-items-separator (&optional eol)
+ "Set up test of command interaction with done items separator.
+With non-nil argument EOL, return the position at the end of the
+separator, otherwise, return the position at the beginning."
+ (todo-test--show 1)
+ (goto-char (point-max))
+ ;; See comment about recentering in todo-test-raise-lower-priority.
+ (set-window-buffer nil (current-buffer))
+ (todo-toggle-view-done-items)
+ ;; FIXME: Point should now be on the first done item, and in batch
+ ;; testing it is, so we have to move back one line to the done items
+ ;; separator; but for some reason, in the graphical test
+ ;; environment, it stays on the last empty line of the todo items
+ ;; section, so there we have to advance one character to the done
+ ;; items separator.
+ (if (display-graphic-p)
+ (forward-char)
+ (forward-line -1))
+ (if eol (forward-char)))
+
+(ert-deftest todo-test-done-items-separator01-bol () ; bug#32343
+ "Test item copying and here insertion at BOL of separator.
+Both should be user errors."
+ (with-todo-test
+ (todo-test--done-items-separator)
+ (let* ((copy-err "Item copying is not valid here")
+ (here-err "Item insertion is not valid here")
+ (insert-item-test (lambda (where)
+ (should-error (todo-insert-item--basic
+ nil nil nil nil where)))))
+ (should (string= copy-err (cadr (funcall insert-item-test 'copy))))
+ (should (string= here-err (cadr (funcall insert-item-test 'here)))))))
+
+(ert-deftest todo-test-done-items-separator01-eol () ; bug#32343
+ "Test item copying and here insertion at EOL of separator.
+Both should be user errors."
+ (with-todo-test
+ (todo-test--done-items-separator 'eol)
+ (let* ((copy-err "Item copying is not valid here")
+ (here-err "Item insertion is not valid here")
+ (insert-item-test (lambda (where)
+ (should-error (todo-insert-item--basic
+ nil nil nil nil where)))))
+ (should (string= copy-err (cadr (funcall insert-item-test 'copy))))
+ (should (string= here-err (cadr (funcall insert-item-test 'here)))))))
+
+(ert-deftest todo-test-done-items-separator02-bol () ; bug#32343
+ "Test item editing commands at BOL of done items separator.
+They should all be noops."
+ (with-todo-test
+ (todo-test--done-items-separator)
+ (should-not (todo-item-done))
+ (should-not (todo-raise-item-priority))
+ (should-not (todo-lower-item-priority))
+ (should-not (called-interactively-p #'todo-set-item-priority))
+ (should-not (called-interactively-p #'todo-move-item))
+ (should-not (called-interactively-p #'todo-delete-item))
+ (should-not (called-interactively-p #'todo-edit-item))))
+
+(ert-deftest todo-test-done-items-separator02-eol () ; bug#32343
+ "Test item editing command at EOL of done items separator.
+They should all be noops."
+ (with-todo-test
+ (todo-test--done-items-separator 'eol)
+ (should-not (todo-item-done))
+ (should-not (todo-raise-item-priority))
+ (should-not (todo-lower-item-priority))
+ (should-not (called-interactively-p #'todo-set-item-priority))
+ (should-not (called-interactively-p #'todo-move-item))
+ (should-not (called-interactively-p #'todo-delete-item))
+ (should-not (called-interactively-p #'todo-edit-item))))
+
+(ert-deftest todo-test-done-items-separator03-bol () ; bug#32343
+ "Test item marking at BOL of done items separator.
+This should be a noop, adding no marks to the category."
+ (with-todo-test
+ (todo-test--done-items-separator)
+ (call-interactively #'todo-toggle-mark-item)
+ (should-not (assoc (todo-current-category) todo-categories-with-marks))))
+
+(ert-deftest todo-test-done-items-separator03-eol () ; bug#32343
+ "Test item marking at EOL of done items separator.
+This should be a noop, adding no marks to the category."
+ (with-todo-test
+ (todo-test--done-items-separator 'eol)
+ (call-interactively #'todo-toggle-mark-item)
+ (should-not (assoc (todo-current-category) todo-categories-with-marks))))
+
+(ert-deftest todo-test-done-items-separator04-bol () ; bug#32343
+ "Test moving to previous item from BOL of done items separator.
+This should move point to the last not done todo item."
+ (with-todo-test
+ (todo-test--done-items-separator)
+ (let ((last-item (save-excursion
+ ;; Move to empty line after last todo item.
+ (forward-line -1)
+ (todo-previous-item)
+ (todo-item-string))))
+ (should (string= last-item (save-excursion
+ (todo-previous-item)
+ (todo-item-string)))))))
+
+(ert-deftest todo-test-done-items-separator04-eol () ; bug#32343
+ "Test moving to previous item from EOL of done items separator.
+This should move point to the last not done todo item."
+ (with-todo-test
+ (todo-test--done-items-separator 'eol)
+ (let ((last-item (save-excursion
+ ;; Move to empty line after last todo item.
+ (forward-line -1)
+ (todo-previous-item)
+ (todo-item-string))))
+ (should (string= last-item (save-excursion
+ (todo-previous-item)
+ (todo-item-string)))))))
+
+(ert-deftest todo-test-done-items-separator05-bol () ; bug#32343
+ "Test moving to next item from BOL of done items separator.
+This should move point to the first done todo item."
+ (with-todo-test
+ (todo-test--done-items-separator)
+ (let ((first-done (save-excursion
+ ;; Move to empty line after last todo item.
+ (forward-line -1)
+ (todo-next-item)
+ (todo-item-string))))
+ (should (string= first-done (save-excursion
+ (todo-next-item)
+ (todo-item-string)))))))
+
+(ert-deftest todo-test-done-items-separator05-eol () ; bug#32343
+ "Test moving to next item from EOL of done items separator.
+This should move point to the first done todo item."
+ (with-todo-test
+ (todo-test--done-items-separator 'eol)
+ (let ((first-done (save-excursion
+ ;; Move to empty line after last todo item.
+ (forward-line -1)
+ (todo-next-item)
+ (todo-item-string))))
+ (should (string= first-done (save-excursion
+ (todo-next-item)
+ (todo-item-string)))))))
+
+;; Item highlighting uses hl-line-mode, which enables highlighting in
+;; post-command-hook. For some reason, in the test environment, the
+;; hook function is not automatically run, so after enabling item
+;; highlighting, use ert-simulate-command around the next command,
+;; which explicitly runs the hook function.
+(ert-deftest todo-test-done-items-separator06-bol () ; bug#32343
+ "Test enabling item highlighting at BOL of done items separator.
+Subsequently moving to an item should show it highlighted."
+ (with-todo-test
+ (todo-test--done-items-separator)
+ (call-interactively #'todo-toggle-item-highlighting)
+ (ert-simulate-command '(todo-previous-item))
+ (should (eq 'hl-line (get-char-property (point) 'face)))))
+
+(ert-deftest todo-test-done-items-separator06-eol () ; bug#32343
+ "Test enabling item highlighting at EOL of done items separator.
+Subsequently moving to an item should show it highlighted."
+ (with-todo-test
+ (todo-test--done-items-separator 'eol)
+ (todo-toggle-item-highlighting)
+ (forward-line -1)
+ (ert-simulate-command '(todo-previous-item))
+ (should (eq 'hl-line (get-char-property (point) 'face)))))
+
+(ert-deftest todo-test-done-items-separator07 () ; bug#32343
+ "Test item highlighting when crossing done items separator.
+The highlighting should remain enabled."
+ (with-todo-test
+ (todo-test--done-items-separator)
+ (todo-previous-item)
+ (todo-toggle-item-highlighting)
+ (todo-next-item) ; Now on empty line above separator.
+ (forward-line) ; Now on separator.
+ (ert-simulate-command '(forward-line)) ; Now on first done item.
+ (should (eq 'hl-line (get-char-property (point) 'face)))))
+
+(ert-deftest todo-test-current-file-in-edit-mode () ; bug#32437
+ "Test the value of todo-current-todo-file in todo-edit-mode."
+ (with-todo-test
+ (todo-test--show 1)
+ ;; The preceding calls todo-mode but does not run pre-command-hook
+ ;; in the test environment, thus failing to set
+ ;; todo-global-current-todo-file, which is needed for the test
+ ;; after todo-edit-item--text. So force the hook function to run.
+ (ert-simulate-command '(todo-mode))
+ (let ((curfile todo-current-todo-file))
+ (should (equal curfile todo-test-file-1))
+ (todo-edit-item--text 'multiline)
+ (should (equal todo-current-todo-file curfile))
+ (todo-edit-quit)
+ (todo-edit-file)
+ (should (equal todo-current-todo-file curfile))
+ (todo-edit-quit))
+ (todo-find-archive)
+ (let ((curfile todo-current-todo-file))
+ (should (equal curfile todo-test-archive-1))
+ (todo-edit-file)
+ (should (equal todo-current-todo-file curfile)))))
+
+(ert-deftest todo-test-edit-quit () ; bug#32437
+ "Test result of exiting todo-edit-mode on a whole file.
+Exiting should return to the same todo-mode or todo-archive-mode
+buffer from which the editing command was invoked."
+ (with-todo-test
+ (todo-test--show 1)
+ (let ((buf (current-buffer)))
+ (todo-edit-file)
+ (todo-edit-quit)
+ (should (eq (current-buffer) buf))
+ (should (eq major-mode 'todo-mode))
+ (todo-find-archive)
+ (let ((buf (current-buffer)))
+ (todo-edit-file)
+ (todo-edit-quit)
+ (should (eq (current-buffer) buf))
+ (should (eq major-mode 'todo-archive-mode))))))
+
+(defun todo-test--add-file (file cat)
+ "Add file FILE with category CAT to todo-files and show it.
+This provides a noninteractive API for todo-add-file for use in
+automatic testing."
+ (let ((file0 (ert-resource-file (concat file ".todo")))
+ todo-add-item-if-new-category) ; Don't need an item in cat.
+ (cl-letf (((symbol-function 'todo-read-file-name)
+ (lambda (_prompt) file0))
+ ((symbol-function 'todo-read-category)
+ (lambda (_prompt &optional _match-type _file) (cons cat file0))))
+ (call-interactively 'todo-add-file) ; Interactive to call todo-show.
+ (todo-add-category file0 cat))))
+
+(defun todo-test--delete-file ()
+ "Delete current todo file without prompting."
+ (cl-letf (((symbol-function 'yes-or-no-p)
+ (lambda (_prompt) t)))
+ (todo-delete-file)))
+
+(ert-deftest todo-test-add-and-delete-file () ; bug#32627
+ "Test adding a new todo file and then deleting it.
+Calling todo-show should display the last current todo file, not
+necessarily the new file. After deleting the new file, todo-show
+should display the previously current (or default) todo file."
+ (with-todo-test
+ (todo-show)
+ (should (equal todo-current-todo-file todo-test-file-1))
+ (let* ((file (concat todo-directory "todo-test-2.todo"))
+ (file-nb (file-name-base file))
+ (cat "cat21"))
+ (todo-test--add-file file-nb cat) ; Add new file and show it.
+ (should (equal todo-current-todo-file file))
+ (todo-quit) ; Quitting todo-mode displays previous buffer.
+ (should (equal todo-current-todo-file todo-test-file-1))
+ (switch-to-buffer "*scratch*")
+ (todo-show) ; Show the last current todo-file (not the new one).
+ (should (equal todo-current-todo-file todo-test-file-1))
+ (switch-to-buffer (get-file-buffer file)) ; Back to new file.
+ (should (equal todo-current-todo-file file))
+ (todo-test--delete-file)
+ (todo-show) ; Back to old file.
+ (should (equal todo-current-todo-file todo-test-file-1))
+ (delete-file (concat file "~")))))
+
+(ert-deftest todo-test-edit-item-date-month () ; bug#42976 #3 and #4
+ "Test incrementing and decrementing the month of an item's date.
+If the change in month crosses a year boundary, the year of the
+item's date should be adjusted accordingly."
+ (with-todo-test
+ (todo-test--show 4)
+ (let ((current-prefix-arg t) ; For todo-edit-item--header.
+ (get-date (lambda ()
+ (save-excursion
+ (todo-date-string-matcher (pos-eol))
+ (buffer-substring-no-properties (match-beginning 1)
+ (match-end 0))))))
+ (should (equal (funcall get-date) "Jan 1, 2020"))
+ (todo-edit-item--header 'month 0)
+ (should (equal (funcall get-date) "Jan 1, 2020"))
+ (todo-edit-item--header 'month 1)
+ (should (equal (funcall get-date) "Feb 1, 2020"))
+ (todo-edit-item--header 'month -1)
+ (should (equal (funcall get-date) "Jan 1, 2020"))
+ (todo-edit-item--header 'month -1)
+ (should (equal (funcall get-date) "Dec 1, 2019"))
+ (todo-edit-item--header 'month 1)
+ (should (equal (funcall get-date) "Jan 1, 2020"))
+ (todo-edit-item--header 'month 12)
+ (should (equal (funcall get-date) "Jan 1, 2021"))
+ (todo-edit-item--header 'month -12)
+ (should (equal (funcall get-date) "Jan 1, 2020"))
+ (todo-edit-item--header 'month -13)
+ (should (equal (funcall get-date) "Dec 1, 2018"))
+ (todo-edit-item--header 'month 7)
+ (should (equal (funcall get-date) "Jul 1, 2019"))
+ (todo-edit-item--header 'month 6)
+ (should (equal (funcall get-date) "Jan 1, 2020"))
+ (todo-edit-item--header 'month 23)
+ (should (equal (funcall get-date) "Dec 1, 2021"))
+ (todo-edit-item--header 'month -23)
+ (should (equal (funcall get-date) "Jan 1, 2020"))
+ (todo-edit-item--header 'month 24)
+ (should (equal (funcall get-date) "Jan 1, 2022"))
+ (todo-edit-item--header 'month -24)
+ (should (equal (funcall get-date) "Jan 1, 2020"))
+ (todo-edit-item--header 'month 25)
+ (should (equal (funcall get-date) "Feb 1, 2022"))
+ (todo-edit-item--header 'month -25)
+ (should (equal (funcall get-date) "Jan 1, 2020")))))
+
+(ert-deftest todo-test-multiline-item-indentation-1 ()
+ "Test inserting a multine item containing a hard line break.
+After insertion the second line of the item should begin with a
+tab character."
+ (with-todo-test
+ (let* ((item0 "Test inserting a multine item")
+ (item1 "containing a hard line break.")
+ (item (concat item0 "\n" item1)))
+ (todo-test--show 1)
+ (todo-test--insert-item item 1)
+ (re-search-forward (concat todo-date-string-start todo-date-pattern
+ (regexp-quote todo-nondiary-end) " ")
+ (pos-eol) t)
+ (should (looking-at (regexp-quote (concat item0 "\n\t" item1)))))))
+
+(ert-deftest todo-test-multiline-item-indentation-2 () ; bug#43068
+ "Test editing an item by adding text on a new line.
+After quitting todo-edit-mode the second line of the item should
+begin with a tab character."
+ (with-todo-test
+ (todo-test--show 2)
+ (let* ((item0 (todo-item-string))
+ (item1 "Second line."))
+ (todo-edit-item--text 'multiline)
+ (insert (concat "\n" item1))
+ (todo-edit-quit)
+ (goto-char (pos-bol))
+ (should (looking-at (regexp-quote (concat item0 "\n\t" item1)))))))
+
+(ert-deftest todo-test-multiline-item-indentation-3 ()
+ "Test adding an unindented new line to an item using todo-edit-file.
+Attempting to quit todo-edit-mode should signal a user-error,
+since all non-initial item lines must begin with whitespace."
+ (with-todo-test
+ (todo-test--show 2)
+ (let* ((item0 (todo-item-string))
+ (item1 "Second line."))
+ (todo-edit-file)
+ (should (looking-at (regexp-quote item0)))
+ (goto-char (pos-eol))
+ (insert (concat "\n" item1))
+ (should-error (todo-edit-quit) :type 'user-error))))
(provide 'todo-mode-tests)
;;; todo-mode-tests.el ends here