;; icalendar-tests.el --- Test suite for icalendar.el
-;; Copyright (C) 2005, 2008-2012 Free Software Foundation, Inc.
+;; Copyright (C) 2005, 2008-2014 Free Software Foundation, Inc.
;; Author: Ulf Jasper <ulf.jasper@web.de>
;; Created: March 2005
(should (string= (concat "yyyDTSTARTyyy")
(icalendar--create-uid entry-full contents)))))
-(ert-deftest icalendar--calendar-style ()
- "Test for `icalendar--date-style'."
- (dolist (calendar-date-style '(iso american european))
- (should (eq (icalendar--date-style) calendar-date-style)))
- (let ((cds calendar-date-style)
- (european-calendar-style t))
- (makunbound 'calendar-date-style)
- (should (eq (icalendar--date-style) 'european))
- (with-no-warnings (setq european-calendar-style nil)) ;still get warning!?! FIXME
- (should (eq (icalendar--date-style) 'american))
- (setq calendar-date-style cds)))
-
(ert-deftest icalendar-convert-anniversary-to-ical ()
"Test method for `icalendar--convert-anniversary-to-ical'."
(let* ((calendar-date-style 'iso)
result)
(setq result (icalendar--convert-anniversary-to-ical
"" "%%(diary-anniversary 1964 6 30) g"))
- (should (= 2 (length result)))
+ (should (consp result))
(should (string= (concat
"\nDTSTART;VALUE=DATE:19640630"
"\nDTEND;VALUE=DATE:19640701"
"\nRRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=06;BYMONTHDAY=30")
(car result)))
- (should (string= "g" (cadr result)))))
+ (should (string= "g" (cdr result)))))
(ert-deftest icalendar--convert-cyclic-to-ical ()
"Test method for `icalendar--convert-cyclic-to-ical'."
result)
(setq result (icalendar--convert-block-to-ical
"" "%%(diary-block 2004 7 19 2004 8 27) Sommerferien"))
- (should (= 2 (length result)))
+ (should (consp result))
(should (string= (concat
"\nDTSTART;VALUE=DATE:20040719"
"\nDTEND;VALUE=DATE:20040828")
(car result)))
- (should (string= "Sommerferien" (cadr result)))))
+ (should (string= "Sommerferien" (cdr result)))))
(ert-deftest icalendar--convert-block-to-ical ()
"Test method for `icalendar--convert-block-to-ical'."
result)
(setq result (icalendar--convert-block-to-ical
"" "%%(diary-block 2004 7 19 2004 8 27) Sommerferien"))
- (should (= 2 (length result)))
+ (should (consp result))
(should (string= (concat
"\nDTSTART;VALUE=DATE:20040719"
"\nDTEND;VALUE=DATE:20040828")
(car result)))
- (should (string= "Sommerferien" (cadr result)))))
+ (should (string= "Sommerferien" (cdr result)))))
(ert-deftest icalendar--convert-yearly-to-ical ()
"Test method for `icalendar--convert-yearly-to-ical'."
["January" "February" "March" "April" "May" "June" "July" "August"
"September" "October" "November" "December"]))
(setq result (icalendar--convert-yearly-to-ical "" "May 1 Tag der Arbeit"))
- (should (= 2 (length result)))
+ (should (consp result))
(should (string= (concat
"\nDTSTART;VALUE=DATE:19000501"
"\nDTEND;VALUE=DATE:19000502"
"\nRRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=5;BYMONTHDAY=1")
(car result)))
- (should (string= "Tag der Arbeit" (cadr result)))))
+ (should (string= "Tag der Arbeit" (cdr result)))))
(ert-deftest icalendar--convert-weekly-to-ical ()
"Test method for `icalendar--convert-weekly-to-ical'."
["Sunday" "Monday" "Tuesday" "Wednesday" "Thursday" "Friday"
"Saturday"]))
(setq result (icalendar--convert-weekly-to-ical "" "Monday 8:30 subject"))
- (should (= 2 (length result)))
+ (should (consp result))
(should (string= (concat "\nDTSTART;VALUE=DATE-TIME:20050103T083000"
"\nDTEND;VALUE=DATE-TIME:20050103T093000"
"\nRRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=MO")
(car result)))
- (should (string= "subject" (cadr result)))))
+ (should (string= "subject" (cdr result)))))
+
+(ert-deftest icalendar--convert-sexp-to-ical ()
+ "Test method for `icalendar--convert-sexp-to-ical'."
+ (let* (result
+ (icalendar-export-sexp-enumeration-days 3))
+ ;; test case %%(diary-hebrew-date)
+ (setq result (icalendar--convert-sexp-to-ical "" "%%(diary-hebrew-date)"))
+ (should (consp result))
+ (should (eq icalendar-export-sexp-enumeration-days (length result)))
+ (mapc (lambda (i)
+ (should (consp i))
+ (should (string-match "Hebrew date (until sunset): .*" (cdr i))))
+ result)))
+
+(ert-deftest icalendar--convert-to-ical ()
+ "Test method for `icalendar--convert-to-ical'."
+ (let* (result
+ (icalendar-export-sexp-enumerate-all t)
+ (icalendar-export-sexp-enumeration-days 3)
+ (calendar-date-style 'iso))
+ ;; test case: %%(diary-anniversary 1642 12 25) Newton
+ ;; forced enumeration not matching the actual day --> empty
+ (setq result (icalendar--convert-sexp-to-ical
+ "" "%%(diary-anniversary 1642 12 25) Newton's birthday"
+ (encode-time 1 1 1 6 12 2014)))
+ (should (null result))
+ ;; test case: %%(diary-anniversary 1642 12 25) Newton
+ ;; enumeration does match the actual day -->
+ (setq result (icalendar--convert-sexp-to-ical
+ "" "%%(diary-anniversary 1642 12 25) Newton's birthday"
+ (encode-time 1 1 1 24 12 2014)))
+ (should (= 1 (length result)))
+ (should (consp (car result)))
+ (should (string-match
+ "\nDTSTART;VALUE=DATE:20141225\nDTEND;VALUE=DATE:20141226"
+ (car (car result))))
+ (should (string-match "Newton's birthday" (cdr (car result))))))
(ert-deftest icalendar--parse-vtimezone ()
"Test method for `icalendar--parse-vtimezone'."
result)
;; without time
(setq result (icalendar--convert-ordinary-to-ical "&?" "2010 2 15 subject"))
- (should (= 2 (length result)))
+ (should (consp result))
(should (string= "\nDTSTART;VALUE=DATE:20100215\nDTEND;VALUE=DATE:20100216"
(car result)))
- (should (string= "subject" (cadr result)))
+ (should (string= "subject" (cdr result)))
+
+ ;; with start time
+ (setq result (icalendar--convert-ordinary-to-ical
+ "&?" "&2010 2 15 12:34 s"))
+ (should (consp result))
+ (should (string= (concat "\nDTSTART;VALUE=DATE-TIME:20100215T123400"
+ "\nDTEND;VALUE=DATE-TIME:20100215T133400")
+ (car result)))
+ (should (string= "s" (cdr result)))
;; with time
(setq result (icalendar--convert-ordinary-to-ical
"&?" "&2010 2 15 12:34-23:45 s"))
- (should (= 2 (length result)))
+ (should (consp result))
(should (string= (concat "\nDTSTART;VALUE=DATE-TIME:20100215T123400"
"\nDTEND;VALUE=DATE-TIME:20100215T234500")
(car result)))
- (should (string= "s" (cadr result)))
+ (should (string= "s" (cdr result)))
;; with time, again -- test bug#5549
(setq result (icalendar--convert-ordinary-to-ical
"x?" "x2010 2 15 0:34-1:45 s"))
- (should (= 2 (length result)))
+ (should (consp result))
(should (string= (concat "\nDTSTART;VALUE=DATE-TIME:20100215T003400"
"\nDTEND;VALUE=DATE-TIME:20100215T014500")
(car result)))
- (should (string= "s" (cadr result)))))
+ (should (string= "s" (cdr result)))))
(ert-deftest icalendar--diarytime-to-isotime ()
"Test method for `icalendar--diarytime-to-isotime'."
(should (string= "T120100"
(icalendar--diarytime-to-isotime "1201" "pm")))
(should (string= "T125900"
- (icalendar--diarytime-to-isotime "1259" "pm"))))
+ (icalendar--diarytime-to-isotime "1259" "pm")))
+ (should (string= "T150000"
+ (icalendar--diarytime-to-isotime "3" "pm"))))
(ert-deftest icalendar--datetime-to-diary-date ()
"Test method for `icalendar--datetime-to-diary-date'."
(should (not result))
))
+(ert-deftest icalendar--decode-isodatetime ()
+ "Test `icalendar--decode-isodatetime'."
+ (let ((tz (getenv "TZ"))
+ result)
+ (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")
+
+ (message "%s" (current-time-zone (encode-time 0 0 10 1 1 2013 0)))
+ (message "%s" (current-time-zone (encode-time 0 0 10 1 8 2013 0)))
+
+ ;; testcase: no time zone in input -> keep time as is
+ ;; 1 Jan 2013 10:00
+ (should (equal '(0 0 10 1 1 2013 2 nil 7200)
+ (icalendar--decode-isodatetime "20130101T100000")))
+ ;; 1 Aug 2013 10:00 (DST)
+ (should (equal '(0 0 10 1 8 2013 4 t 10800)
+ (icalendar--decode-isodatetime "20130801T100000")))
+
+ ;; testcase: UTC time zone specifier in input -> convert to local time
+ ;; 31 Dec 2013 23:00 UTC -> 1 Jan 2013 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")))
+
+ )
+ ;; restore time-zone even if something went terribly wrong
+ (setenv "TZ" tz))) )
+
;; ======================================================================
;; Export tests
;; ======================================================================
European style input data must use german month names. American
and ISO style input data must use english month names."
- (let ((tz (cadr (current-time-zone)))
+ (let ((tz (getenv "TZ"))
(calendar-date-style 'iso)
(icalendar-recurring-start-year 2000))
(unwind-protect
(progn
- (set-time-zone-rule "CET")
+;;; (message "Current time zone: %s" (current-time-zone))
+ ;; Use this form so as not to rely on system tz database.
+ ;; Eg hydra.nixos.org.
+ (setenv "TZ" "CET-1CEST,M3.5.0/2,M10.5.0/3")
+;;; (message "Current time zone: %s" (current-time-zone))
(when input-iso
(let ((calendar-month-name-array
["January" "February" "March" "April" "May" "June" "July" "August"
"Saturday"]))
(setq calendar-date-style 'american)
(icalendar-tests--do-test-export input-american expected-output))))
- ;; restore time-zone if something went terribly wrong
- (set-time-zone-rule tz))))
+ ;; restore time-zone even if something went terribly wrong
+ (setenv "TZ" tz))))
(defun icalendar-tests--do-test-export (input expected-output)
"Actually perform export test.
Argument EXPECTED-ISO expected iso style diary string.
Argument EXPECTED-EUROPEAN expected european style diary string.
Argument EXPECTED-AMERICAN expected american style diary string."
- (let ((timezone (cadr (current-time-zone))))
- (set-time-zone-rule "CET")
- (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"))
- (let ((icalendar-import-format "%s%d%l%o%t%u%c%U")
- (icalendar-import-format-summary "%s")
- (icalendar-import-format-location "\n Location: %s")
- (icalendar-import-format-description "\n Desc: %s")
- (icalendar-import-format-organizer "\n Organizer: %s")
- (icalendar-import-format-status "\n Status: %s")
- (icalendar-import-format-url "\n URL: %s")
- (icalendar-import-format-class "\n Class: %s")
- (icalendar-import-format-uid "\n UID: %s")
- calendar-date-style)
- (when expected-iso
- (setq calendar-date-style 'iso)
- (icalendar-tests--do-test-import input expected-iso))
- (when expected-european
- (setq calendar-date-style 'european)
- (icalendar-tests--do-test-import input expected-european))
- (when expected-american
- (setq calendar-date-style 'american)
- (icalendar-tests--do-test-import input expected-american))))
- (set-time-zone-rule timezone)))
+ (let ((timezone (getenv "TZ")))
+ (unwind-protect
+ (progn
+;;; (message "Current time zone: %s" (current-time-zone))
+ ;; Use this form so as not to rely on system tz database.
+ ;; Eg hydra.nixos.org.
+ (setenv "TZ" "CET-1CEST,M3.5.0/2,M10.5.0/3")
+;;; (message "Current time zone: %s" (current-time-zone))
+ (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"))
+ (let ((icalendar-import-format "%s%d%l%o%t%u%c%U")
+ (icalendar-import-format-summary "%s")
+ (icalendar-import-format-location "\n Location: %s")
+ (icalendar-import-format-description "\n Desc: %s")
+ (icalendar-import-format-organizer "\n Organizer: %s")
+ (icalendar-import-format-status "\n Status: %s")
+ (icalendar-import-format-url "\n URL: %s")
+ (icalendar-import-format-class "\n Class: %s")
+ (icalendar-import-format-uid "\n UID: %s")
+ calendar-date-style)
+ (when expected-iso
+ (setq calendar-date-style 'iso)
+ (icalendar-tests--do-test-import input expected-iso))
+ (when expected-european
+ (setq calendar-date-style 'european)
+ (icalendar-tests--do-test-import input expected-european))
+ (when expected-american
+ (setq calendar-date-style 'american)
+ (icalendar-tests--do-test-import input expected-american)))))
+ (setenv "TZ" timezone))))
(defun icalendar-tests--do-test-import (input 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")))
+ ;; 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)
(save-excursion
(find-file temp-file)
+ ;; Check for the mysterious "# coding: ..." header, remove it
+ ;; and give a shout
+ (goto-char (point-min))
+ (when (re-search-forward "# coding: .*?\n" nil t)
+ (message (concat "%s\n"
+ "Found mysterious \"# coding ...\" header! Removing it.\n"
+ "Current Modes: %s, %s\n"
+ "Current test: %s\n"
+ "%s")
+ (make-string 70 ?*)
+ major-mode
+ minor-mode-list
+ (ert-running-test)
+ (make-string 70 ?*))
+ (buffer-disable-undo)
+ (replace-match "")
+ (set-buffer-modified-p nil))
+
(let ((result (buffer-substring-no-properties (point-min) (point-max))))
- (should (string= expected-output result)))
+ (should (string= expected-output result)))
(kill-buffer (find-buffer-visiting temp-file))
(delete-file temp-file))))
(should (string= org-input cycled)))))
;; clean up
(kill-buffer (find-buffer-visiting temp-diary))
- (save-excursion
- (set-buffer (find-buffer-visiting temp-ics))
+ (with-current-buffer (find-buffer-visiting temp-ics)
(set-buffer-modified-p nil)
(kill-buffer (current-buffer)))
(delete-file temp-diary)