changeset 109686:111f90199914

Fixed bug#6766 (icalendar.el) lisp/ChangeLog: * calendar/icalendar.el (icalendar-uid-format): Doc fix. (icalendar--split-value): Fixed splitting regexp. (Bug#6766) (icalendar--get-weekday-numbers): New (icalendar--create-uid, icalendar-export-region) (icalendar--parse-summary-and-rest): Code formatting. (icalendar--convert-recurring-to-diary): Handle multiple byday values in weekly rules. (Bug#6766) test/ChangeLog: * icalendar-testsuite.el (icalendar-testsuite-run): Added internal tests. (icalendar-testsuite--trim, icalendar-testsuite--compare-strings) (icalendar-testsuite--run-internal-tests): New. (icalendar-testsuite--test-convert-ordinary-to-ical) (icalendar-testsuite--test-convert-block-to-ical) (icalendar-testsuite--test-convert-anniversary-to-ical) (icalendar-testsuite--test-parse-vtimezone) (icalendar-testsuite--do-test-export): Code formatting. (icalendar-testsuite--test-parse-vtimezone): Doc fix. (icalendar-testsuite--do-test-import) (icalendar-testsuite--do-test-cycle): Use icalendar-testsuite--compare-strings (icalendar-testsuite--run-import-tests): Comment added. (icalendar-testsuite--run-import-tests) (icalendar-testsuite--run-real-world-tests): Fixed expected results.
author Ulf Jasper <ulf.jasper@web.de>
date Sun, 08 Aug 2010 19:42:47 +0200
parents 5cfe70ae40e5
children d6c4fa12ba52
files lisp/ChangeLog lisp/calendar/icalendar.el test/ChangeLog test/icalendar-testsuite.el
diffstat 4 files changed, 260 insertions(+), 84 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/ChangeLog	Sun Aug 08 19:51:56 2010 +0300
+++ b/lisp/ChangeLog	Sun Aug 08 19:42:47 2010 +0200
@@ -1,3 +1,13 @@
+2010-08-08  Ulf Jasper  <ulf.jasper@web.de>
+
+	* calendar/icalendar.el (icalendar-uid-format): Doc fix.
+	(icalendar--split-value): Fixed splitting regexp. (Bug#6766)
+	(icalendar--get-weekday-numbers): New
+	(icalendar--create-uid, icalendar-export-region)
+	(icalendar--parse-summary-and-rest): Code formatting.
+	(icalendar--convert-recurring-to-diary): Handle multiple byday
+	values in weekly rules. (Bug#6766)
+
 2010-08-08  Jay Belanger  <jay.p.belanger@gmail.com>
 
 	* calc/calc.el (calc-trail-mode,calc-refresh): Use `face' property
--- a/lisp/calendar/icalendar.el	Sun Aug 08 19:51:56 2010 +0300
+++ b/lisp/calendar/icalendar.el	Sun Aug 08 19:42:47 2010 +0200
@@ -212,15 +212,15 @@
 
 (defcustom icalendar-uid-format
   "emacs%t%c"
-  "Format of unique ID code (UID) for each iCalendar object.  
-The following specifiers are available: 
+  "Format of unique ID code (UID) for each iCalendar object.
+The following specifiers are available:
 %c COUNTER, an integer value that is increased each time a uid is
-   generated. This may be necessary for systems which do not
+   generated.  This may be necessary for systems which do not
    provide time-resolution finer than a second.
 %h HASH, a hash value of the diary entry,
 %s DTSTART, the start date (excluding time) of the diary entry,
 %t TIMESTAMP, a unique creation timestamp,
-%u USERNAME, the user-login-name.
+%u USERNAME, the variable `user-login-name'.
 
 For example, a value of \"%s_%h@mydomain.com\" will generate a
 UID code for each entry composed of the time of the event, a hash
@@ -427,7 +427,7 @@
         (goto-char (point-min))
         (while
             (re-search-forward
-             "\\([A-Za-z0-9-]+\\)=\\(\\([^;,:]+\\)\\|\"\\([^\"]+\\)\"\\);?"
+             "\\([A-Za-z0-9-]+\\)=\\(\\([^;:]+\\)\\|\"\\([^\"]+\\)\"\\);?"
              nil t)
           (setq param-name (intern (match-string 1)))
           (setq param-value (match-string 2))
@@ -744,6 +744,20 @@
     ;; Error:
     -1))
 
+(defun icalendar--get-weekday-numbers (abbrevweekdays)
+  "Return the list of numbers for the comma-separated ABBREVWEEKDAYS."
+  (when abbrevweekdays
+    (let* ((num -1)
+           (weekday-alist (mapcar (lambda (day)
+                                    (progn
+                                      (setq num (1+ num))
+                                      (cons (downcase day) num)))
+                                  icalendar--weekday-array)))
+      (delq nil
+            (mapcar (lambda (abbrevday)
+                      (cdr (assoc abbrevday weekday-alist)))
+                    (split-string (downcase abbrevweekdays) ","))))))
+
 (defun icalendar--get-weekday-abbrev (weekday)
   "Return the abbreviated WEEKDAY."
   (catch 'found
@@ -912,21 +926,21 @@
 `icalendar--uid-count'.  Returns the UID string."
   (let ((uid icalendar-uid-format))
     
-    (setq uid (replace-regexp-in-string 
-	       "%c" 
+    (setq uid (replace-regexp-in-string
+	       "%c"
 	       (format "%d" icalendar--uid-count)
                uid t t))
     (setq icalendar--uid-count (1+ icalendar--uid-count))
-    (setq uid (replace-regexp-in-string 
+    (setq uid (replace-regexp-in-string
 	       "%t"
 	       (format "%d%d%d" (car (current-time))
 		       (cadr (current-time))
-		       (car (cddr (current-time)))) 
+		       (car (cddr (current-time))))
 	       uid t t))
-    (setq uid (replace-regexp-in-string 
-	       "%h" 
+    (setq uid (replace-regexp-in-string
+	       "%h"
 	       (format "%d" (abs (sxhash entry-full))) uid t t))
-    (setq uid (replace-regexp-in-string 
+    (setq uid (replace-regexp-in-string
 	       "%u" (or user-login-name "UNKNOWN_USER") uid t t))
     (let ((dtstart (if (string-match "^DTSTART[^:]*:\\([0-9]*\\)" contents)
                        (substring contents (match-beginning 1) (match-end 1))
@@ -1008,7 +1022,7 @@
                 (if url
                     (setq contents (concat contents "\nURL:" url))))
 
-	      (setq header (concat "\nBEGIN:VEVENT\nUID:" 
+	      (setq header (concat "\nBEGIN:VEVENT\nUID:"
 				   (icalendar--create-uid entry-full contents)))
               (setq result (concat result header contents "\nEND:VEVENT")))
           ;; handle errors
@@ -1126,7 +1140,7 @@
                (list "%u"
                      (concat "\\(" icalendar-import-format-url "\\)??"))))
 	;; Need the \' regexp in order to detect multi-line items
-        (setq s (concat "\\`" 
+        (setq s (concat "\\`"
 			   (icalendar--rris "%s" "\\(.*?\\)" s nil t)
                         "\\'"))
         (if (string-match s summary-and-rest)
@@ -2057,39 +2071,47 @@
           ))
       )
     (cond ((string-equal frequency "WEEKLY")
-           (if (not start-t)
-               (progn
-                 ;; weekly and all-day
-                 (icalendar--dmsg "weekly all-day")
-                 (if until
-                     (setq result
-                           (format
-                            (concat "%%%%(and "
-                                    "(diary-cyclic %d %s) "
-                                    "(diary-block %s %s))")
-                            (* interval 7)
-                            dtstart-conv
-                            dtstart-conv
-                            (if count until-1-conv until-conv)
-                            ))
-                   (setq result
-                         (format "%%%%(and (diary-cyclic %d %s))"
-                                 (* interval 7)
-                                 dtstart-conv))))
-             ;; weekly and not all-day
-             (let* ((byday (cadr (assoc 'BYDAY rrule-props)))
-                    (weekday
-                     (icalendar--get-weekday-number byday)))
+	   (let* ((byday (cadr (assoc 'BYDAY rrule-props)))
+		  (weekdays
+		   (icalendar--get-weekday-numbers byday))
+		  (weekday-clause
+		   (when (> (length weekdays) 1)
+		     (format "(memq (calendar-day-of-week date) '%s) "
+			     weekdays))))
+	     (if (not start-t)
+		 (progn
+		   ;; weekly and all-day
+		   (icalendar--dmsg "weekly all-day")
+		   (if until
+		       (setq result
+			     (format
+			      (concat "%%%%(and "
+				      "%s"
+				      "(diary-block %s %s))")
+			      (or weekday-clause
+				  (format "(diary-cyclic %d %s) "
+					  (* interval 7)
+					  dtstart-conv))
+			      (if count until-1-conv until-conv)
+			      ))
+		       (setq result
+			     (format "%%%%(and %s(diary-cyclic %d %s))"
+				     (or weekday-clause "")
+				     (if weekday-clause 1 (* interval 7))
+				     dtstart-conv))))
+               ;; weekly and not all-day
                (icalendar--dmsg "weekly not-all-day")
                (if until
                    (setq result
                          (format
                           (concat "%%%%(and "
-                                  "(diary-cyclic %d %s) "
+                                  "%s"
                                   "(diary-block %s %s)) "
                                   "%s%s%s")
-                          (* interval 7)
-                          dtstart-conv
+			  (or weekday-clause
+			      (format "(diary-cyclic %d %s) "
+				      (* interval 7)
+				      dtstart-conv))
                           dtstart-conv
                           until-conv
                           (or start-t "")
@@ -2100,10 +2122,11 @@
                  ;; DTEND;VALUE=DATE-TIME:20030919T113000
                  (setq result
                        (format
-                        "%%%%(and (diary-cyclic %s %s)) %s%s%s"
-                        (* interval 7)
-                        dtstart-conv
-                        (or start-t "")
+                        "%%%%(and %s(diary-cyclic %d %s)) %s%s%s"
+			(or weekday-clause "")
+			(if weekday-clause 1 (* interval 7))
+			dtstart-conv
+			(or start-t "")
                         (if end-t "-" "") (or end-t "")))))))
           ;; yearly
           ((string-equal frequency "YEARLY")
--- a/test/ChangeLog	Sun Aug 08 19:51:56 2010 +0300
+++ b/test/ChangeLog	Sun Aug 08 19:42:47 2010 +0200
@@ -1,3 +1,20 @@
+2010-08-08  Ulf Jasper  <ulf.jasper@web.de>
+
+	* icalendar-testsuite.el (icalendar-testsuite-run): Added internal tests.
+	(icalendar-testsuite--trim, icalendar-testsuite--compare-strings)
+	(icalendar-testsuite--run-internal-tests): New.
+	(icalendar-testsuite--test-convert-ordinary-to-ical)
+	(icalendar-testsuite--test-convert-block-to-ical)
+	(icalendar-testsuite--test-convert-anniversary-to-ical)
+	(icalendar-testsuite--test-parse-vtimezone)
+	(icalendar-testsuite--do-test-export): Code formatting.
+	(icalendar-testsuite--test-parse-vtimezone): Doc fix.
+	(icalendar-testsuite--do-test-import)
+	(icalendar-testsuite--do-test-cycle): Use icalendar-testsuite--compare-strings
+	(icalendar-testsuite--run-import-tests): Comment added.
+	(icalendar-testsuite--run-import-tests)
+	(icalendar-testsuite--run-real-world-tests): Fixed expected results.
+
 2010-06-25  Chong Yidong  <cyd@stupidchicken.com>
 
 	* redisplay-testsuite.el (test-redisplay-3): New test.
--- a/test/icalendar-testsuite.el	Sun Aug 08 19:51:56 2010 +0300
+++ b/test/icalendar-testsuite.el	Sun Aug 08 19:42:47 2010 +0200
@@ -33,6 +33,7 @@
 (defun icalendar-testsuite-run ()
   "Run icalendar test suite."
   (interactive)
+  (icalendar-testsuite--run-internal-tests)
   (icalendar-testsuite--run-function-tests)
   (icalendar-testsuite--run-import-tests)
   (icalendar-testsuite--run-export-tests)
@@ -41,6 +42,44 @@
   (message "All icalendar tests finished successfully."))
 
 ;; ======================================================================
+;; internal
+;; ======================================================================
+(defun icalendar-testsuite--trim (string)
+  "Remove leading and trailing whitespace from STRING."
+  (replace-regexp-in-string "[ \t\n]+\\'" ""
+                            (replace-regexp-in-string "\\`[ \t\n]+" "" string)))
+
+(defun icalendar-testsuite--compare-strings (str1 str2)
+  "Compare strings STR1 and STR2.
+Return t if strings are equal, else return substring indicating first difference.
+FIXME: make this a little smarter."
+  (let* ((s1 (icalendar-testsuite--trim str1))
+         (s2 (icalendar-testsuite--trim str2))
+         (result (compare-strings s1 0 nil s2 0 nil))
+         (len (length str2)))
+    (if (numberp result)
+        (if (> result 0)
+            (concat "..." (substring str2 (- result 1)
+                                     (min len (+ (- result 1) 3))) "...")
+          (concat "..." (substring str2 (- (+ result 1))
+                                   (min len  (+ (- (+ result 1)) 3))) "..."))
+      t)))
+
+(defun icalendar-testsuite--run-internal-tests ()
+  "Run icalendar-testsuite internal tests."
+  (assert (equal t (icalendar-testsuite--compare-strings " abcde" "abcde ")))
+  (assert
+   (string= "...def..."
+            (icalendar-testsuite--compare-strings "abcxe" "abcdefghijklmn")))
+  (assert (string= "...xe..."
+                   (icalendar-testsuite--compare-strings "abcde" "abcxe")))
+  (assert (string= "...ddd..."
+           (icalendar-testsuite--compare-strings "abc" "abcdddddd")))
+  (assert (string= "......"
+                   (icalendar-testsuite--compare-strings "abcdefghij" "abc"))))
+  
+
+;; ======================================================================
 ;; Test methods for functions
 ;; ======================================================================
 (defun icalendar-testsuite--run-function-tests ()
@@ -260,7 +299,7 @@
     (assert (string= "subject" (cadr result)))
   
     ;; with time
-    (setq result (icalendar--convert-ordinary-to-ical 
+    (setq result (icalendar--convert-ordinary-to-ical
                   "&?" "&2010 2 15 12:34-23:45 s"))
     (assert (= 2 (length result)))
     (assert (string=  (concat "\nDTSTART;VALUE=DATE-TIME:20100215T123400"
@@ -269,7 +308,7 @@
     (assert (string= "s" (cadr result)))
 
     ;; with time, again -- test bug#5549
-    (setq result (icalendar--convert-ordinary-to-ical 
+    (setq result (icalendar--convert-ordinary-to-ical
                   "x?" "x2010 2 15 0:34-1:45 s"))
     (assert (= 2 (length result)))
     (assert (string=  (concat "\nDTSTART;VALUE=DATE-TIME:20100215T003400"
@@ -312,7 +351,7 @@
   "Test method for `icalendar--convert-block-to-ical'."
   (let* ((calendar-date-style 'iso)
          result)
-    (setq result (icalendar--convert-block-to-ical 
+    (setq result (icalendar--convert-block-to-ical
                   "" "%%(diary-block 2004 7 19 2004 8 27) Sommerferien"))
     (assert (= 2 (length result)))
     (assert (string= (concat
@@ -325,7 +364,7 @@
   "Test method for `icalendar--convert-cyclic-to-ical'."
   (let* ((calendar-date-style 'iso)
          result)
-    (setq result (icalendar--convert-block-to-ical 
+    (setq result (icalendar--convert-block-to-ical
                   "" "%%(diary-block 2004 7 19 2004 8 27) Sommerferien"))
     (assert (= 2 (length result)))
     (assert (string= (concat
@@ -338,7 +377,7 @@
   "Test method for `icalendar--convert-anniversary-to-ical'."
   (let* ((calendar-date-style 'iso)
          result)
-    (setq result (icalendar--convert-anniversary-to-ical 
+    (setq result (icalendar--convert-anniversary-to-ical
                   "" "%%(diary-anniversary 1964 6 30) g"))
     (assert (= 2 (length result)))
     (assert (string= (concat
@@ -386,6 +425,7 @@
     ))
 
 (defun icalendar-testsuite--test-parse-vtimezone ()
+  "Test method for `icalendar--parse-vtimezone'."
   (let (vtimezone result)
     (setq vtimezone (icalendar-testsuite--get-ical-event "BEGIN:VTIMEZONE
 TZID:thename
@@ -406,7 +446,8 @@
     (setq result (icalendar--parse-vtimezone vtimezone))
     (assert (string= "thename" (car result)))
     (message (cdr result))
-    (assert (string= "STD-02:00DST-03:00,M3.5.0/03:00:00,M10.5.0/04:00:00" (cdr result)))
+    (assert (string= "STD-02:00DST-03:00,M3.5.0/03:00:00,M10.5.0/04:00:00"
+                     (cdr result)))
     (setq vtimezone (icalendar-testsuite--get-ical-event "BEGIN:VTIMEZONE
 TZID:anothername
 BEGIN:STANDARD
@@ -457,7 +498,7 @@
         (icalendar-testsuite--do-test-export input-iso expected-output)))
     (when input-european
       (let ((calendar-month-name-array
-             ["Januar" "Februar" "März" "April" "Mai" "Juni" "Juli" "August"
+             ["Januar" "Februar" "März" "April" "Mai" "Juni" "Juli" "August"
               "September" "Oktober" "November" "Dezember"])
             (calendar-day-name-array
              ["Sonntag" "Montag" "Dienstag" "Mittwoch" "Donnerstag" "Freitag"
@@ -511,12 +552,18 @@
 \\s-*$"
                                     nil t)))
         (error
-         "Export test failed! Input: `%s'\nFound:\n\n%s\n\nbut expected\n\n%s"
+         "Export test failed! Input: `%s'\nFound:\n\n%s\n\nbut expected\n\n%s\n%s"
          input
          (or (and (match-beginning 1)
-                  (buffer-substring-no-properties (match-beginning 1) (match-end 1)))
+                  (buffer-substring-no-properties (match-beginning 1)
+                                                  (match-end 1)))
              "<nil>")
-         (or expected-output "<nil>"))))
+         (or expected-output "<nil>")
+         (icalendar-testsuite--compare-strings   (or (and (match-beginning 1)
+                  (buffer-substring-no-properties (match-beginning 1)
+                                                  (match-end 1)))
+             "<nil>")
+         (or expected-output "<nil>")))))
     (kill-buffer (find-buffer-visiting temp-file))
     (delete-file temp-file)))
 
@@ -571,11 +618,13 @@
     (icalendar-import-buffer temp-file t t)
     (save-excursion
       (find-file temp-file)
-      (let ((result (buffer-substring-no-properties (point-min) (point-max))))
-        (unless (string-match (concat "^\\s-*" expected-output "\\s-*$")
-                              result)
-          (error "Import test failed! Found `%s'\nbut expected `%s'" result
-                 expected-output)))
+      (let* ((result (buffer-substring-no-properties (point-min) (point-max)))
+             (difference
+              (icalendar-testsuite--compare-strings result
+                                                    expected-output)))
+        (if (stringp difference)
+          (error "Import test failed! Found\n`%s'\nbut expected\n`%s'\n%s'"
+                 result expected-output difference)))
       (kill-buffer (find-buffer-visiting temp-file))
       (delete-file temp-file))))
 
@@ -626,9 +675,12 @@
       (when (re-search-forward "\nUID:.*\n" nil t)
         (replace-match "\n"))
       (let ((cycled (buffer-substring-no-properties (point-min) (point-max))))
-        (unless (string-equal org-input cycled)
-          (error "Import test failed! Found `%s'\nbut expected `%s'" cycled
-                 org-input))))
+        (let ((difference (icalendar-testsuite--compare-strings cycled
+                                                                org-input)))
+          (if (stringp difference)
+              (error "Import test failed! Found\n`%s'\nbut expected\n`%s'\n%s'"
+                     cycled org-input difference)))
+        ))
 
     ;; clean up -- Note this is done only if test is passed
     (kill-buffer (find-buffer-visiting temp-diary))
@@ -660,6 +712,7 @@
    "&9/19/2003 non-recurring allday")
 
   (icalendar-testsuite--test-import
+   ;; do not remove the trailing blank after "long"!
    "SUMMARY:long 
  summary
 DTSTART;VALUE=DATE:20030919"
@@ -678,9 +731,17 @@
 DTEND;VALUE=DATE:20040828
 DTSTAMP:20031103T011641Z
 "
-   "&%%(and (diary-block 2004 7 19 2004 8 27)) Sommerferien"
-   "&%%(and (diary-block 19 7 2004 27 8 2004)) Sommerferien"
-   "&%%(and (diary-block 7 19 2004 8 27 2004)) Sommerferien")
+   "&%%(and (diary-block 2004 7 19 2004 8 27)) Sommerferien
+ Status: TENTATIVE
+ Class: PRIVATE
+"
+   "&%%(and (diary-block 19 7 2004 27 8 2004)) Sommerferien
+ Status: TENTATIVE
+ Class: PRIVATE
+"
+   "&%%(and (diary-block 7 19 2004 8 27 2004)) Sommerferien
+ Status: TENTATIVE
+ Class: PRIVATE")
 
   (icalendar-testsuite--test-import
    "UID
@@ -702,9 +763,15 @@
 LAST-MODIFIED
  :20041118T013640Z
 "
-   "&2004/11/23 14:00-14:30 folded summary"
-   "&23/11/2004 14:00-14:30 folded summary"
-   "&11/23/2004 14:00-14:30 folded summary")
+   "&2004/11/23 14:00-14:30 folded summary
+ Status: TENTATIVE
+ Class: PRIVATE"
+   "&23/11/2004 14:00-14:30 folded summary
+ Status: TENTATIVE
+ Class: PRIVATE"
+   "&11/23/2004 14:00-14:30 folded summary
+ Status: TENTATIVE
+ Class: PRIVATE")
   (icalendar-testsuite--test-import
    "UID
  :6161a312-3902-11d9-b512-f764153bb28b
@@ -723,9 +790,15 @@
 DTSTAMP
  :20041118T013641Z
 "
-   "&2004/11/23 14:45-15:45 another example"
-   "&23/11/2004 14:45-15:45 another example"
-   "&11/23/2004 14:45-15:45 another example")
+   "&2004/11/23 14:45-15:45 another example
+ Status: TENTATIVE
+ Class: PRIVATE"
+   "&23/11/2004 14:45-15:45 another example
+ Status: TENTATIVE
+ Class: PRIVATE"
+   "&11/23/2004 14:45-15:45 another example
+ Status: TENTATIVE
+ Class: PRIVATE")
 
   (icalendar-testsuite--test-import
    "SUMMARY:rrule daily
@@ -890,10 +963,55 @@
 SEQUENCE:1
 CREATED:20041127T183329
 "
-   "&%%(and (diary-cyclic 1 2001 12 21) (diary-block 2001 12 21 2001 12 29))  Urlaub"
-   "&%%(and (diary-cyclic 1 21 12 2001) (diary-block 21 12 2001 29 12 2001))  Urlaub"
-   "&%%(and (diary-cyclic 1 12 21 2001) (diary-block 12 21 2001 12 29 2001))  Urlaub")
-  )
+   "&%%(and (diary-cyclic 1 2001 12 21) (diary-block 2001 12 21 2001 12 29))  Urlaub
+ Class: PUBLIC"
+   "&%%(and (diary-cyclic 1 21 12 2001) (diary-block 21 12 2001 29 12 2001))  Urlaub
+ Class: PUBLIC"
+   "&%%(and (diary-cyclic 1 12 21 2001) (diary-block 12 21 2001 12 29 2001))  Urlaub
+ Class: PUBLIC")
+
+  ;;bug#6766 -- multiple byday values in a weekly rrule
+  (icalendar-testsuite--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
+&%%(and (memq (calendar-day-of-week date) '(2 4)) (diary-cyclic 1 2010 4 22)) Tues + Thurs thinking
+ Class: PUBLIC"
+
+"&%%(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
+&%%(and (memq (calendar-day-of-week date) '(2 4)) (diary-cyclic 1 22 4 2010)) Tues + Thurs thinking
+ Class: PUBLIC"
+
+"&%%(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
+&%%(and (memq (calendar-day-of-week date) '(2 4)) (diary-cyclic 1 4 22 2010)) Tues + Thurs thinking
+ Class: PUBLIC")
+)
 
 ;; ======================================================================
 ;; Export tests
@@ -1104,11 +1222,13 @@
    "&9/5/2003 10:30-15:30 On-Site Interview
  Desc: 10:30am - Blah
  Location: Cccc
- Organizer: MAILTO:aaaaaaa@aaaaaaa.com"
+ Organizer: MAILTO:aaaaaaa@aaaaaaa.com
+ Status: CONFIRMED"
    "&5/9/2003 10:30-15:30 On-Site Interview
  Desc: 10:30am - Blah
  Location: Cccc
- Organizer: MAILTO:aaaaaaa@aaaaaaa.com")
+ Organizer: MAILTO:aaaaaaa@aaaaaaa.com
+ Status: CONFIRMED")
 
   ;; 2003-06-18 a
   (icalendar-testsuite--test-import
@@ -1146,11 +1266,13 @@
    "&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"
+ Organizer: MAILTO:xxx@xxxxx.com
+ Status: CONFIRMED"
    "&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")
+ Organizer: MAILTO:xxx@xxxxx.com
+ Status: CONFIRMED")
 
   ;; 2003-06-18 b -- uses timezone
   (icalendar-testsuite--test-import
@@ -1188,7 +1310,7 @@
 \(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
+DESCRIPTION:Viele Zeichen standen hier früher
 SEQUENCE:0
 PRIORITY:5
 CLASS:
@@ -1211,12 +1333,12 @@
 END:VCALENDAR"
    nil
    "&23/6/2003 17:00-18:00 Updated: Dress Rehearsal for ABC01-15
- Desc: Viele Zeichen standen hier früher
+ 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"
    "&6/23/2003 17:00-18:00 Updated: Dress Rehearsal for ABC01-15
- Desc: Viele Zeichen standen hier früher
+ 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")
@@ -1661,9 +1783,13 @@
  :20050128T011209Z"
    nil
    "&%%(and (diary-block 6 2 2005 6 2 2005)) Waitangi Day
- Desc: abcdef"
+ Desc: abcdef
+ Status: CONFIRMED
+ Class: PRIVATE"
    "&%%(and (diary-block 2 6 2005 2 6 2005)) Waitangi Day
- Desc: abcdef")
+ Desc: abcdef
+ Status: CONFIRMED
+ Class: PRIVATE")
 
   ;; 2005-03-01 lt
   (icalendar-testsuite--test-import