[california] Additional tests and fixes for Quick Add parsing



commit a9e7e6deae065640c0ffcec6384444fbf630c154
Author: Jim Nelson <jim yorba org>
Date:   Thu Jun 26 16:21:50 2014 -0700

    Additional tests and fixes for Quick Add parsing
    
    Discovered while working on Quick Add documentation.

 src/component/component-details-parser.vala |   21 ++++++++++-
 src/component/component-event.vala          |    7 +++-
 src/component/component-instance.vala       |    6 +++-
 src/host/host-quick-create-event.vala       |    2 +-
 src/tests/tests-quick-add.vala              |   49 ++++++++++++++++++++++++--
 5 files changed, 75 insertions(+), 10 deletions(-)
---
diff --git a/src/component/component-details-parser.vala b/src/component/component-details-parser.vala
index bf2db73..2cd9f46 100644
--- a/src/component/component-details-parser.vala
+++ b/src/component/component-details-parser.vala
@@ -191,8 +191,15 @@ public class DetailsParser : BaseObject {
             
             // if a recurring rule has been started and are adding to it, drop common prepositions
             // that indicate linkage
-            if (rrule != null && token.casefolded in COMMON_PREPOSITIONS)
-                continue;
+            stack.mark();
+            if (token.casefolded in COMMON_PREPOSITIONS) {
+                if (rrule != null)
+                    continue;
+                
+                if (parse_time(stack.pop(), true))
+                    continue;
+            }
+            stack.restore();
             
             // if a recurring rule has not been started, look for keywords which transform the
             // event into one
@@ -308,6 +315,16 @@ public class DetailsParser : BaseObject {
         if (specifier == null)
             return false;
         
+        // look for single-word date specifiers
+        if (specifier.casefolded in UNIT_WEEKENDS) {
+            Calendar.Date saturday = Calendar.System.today.upcoming(true,
+                date => date.day_of_week == Calendar.DayOfWeek.SAT);
+            Calendar.Date sunday = Calendar.System.today.upcoming(true,
+                date => date.day_of_week == Calendar.DayOfWeek.SUN);
+            
+            return add_date(saturday) && add_date(sunday);
+        }
+        
         // look for day/month specifiers, in any order
         stack.mark();
         {
diff --git a/src/component/component-event.vala b/src/component/component-event.vala
index 99ea3bf..9a14b3d 100644
--- a/src/component/component-event.vala
+++ b/src/component/component-event.vala
@@ -380,8 +380,11 @@ public class Event : Instance, Gee.Comparable<Event> {
     /**
      * @inheritDoc
      */
-    public override bool is_valid() {
-        return base.is_valid() && (date_span != null || exact_time_span != null);
+    public override bool is_valid(bool and_useful) {
+        if (and_useful && String.is_empty(summary))
+            return false;
+        
+        return base.is_valid(and_useful) && (date_span != null || exact_time_span != null);
     }
     
     /**
diff --git a/src/component/component-instance.vala b/src/component/component-instance.vala
index 4444d9c..56c86ab 100644
--- a/src/component/component-instance.vala
+++ b/src/component/component-instance.vala
@@ -348,8 +348,12 @@ public abstract class Instance : BaseObject, Gee.Hashable<Instance> {
      * present with proper values.
      *
      * The presence of { link calendar_source} is not necessary to deem an Instance valid.
+     *
+     * and_useful indicates that, while technically valid according to the iCalendar specification,
+     * the Instance also has optional fields available that the user will almost likely need or
+     * require for the event to be of use.
      */
-    public virtual bool is_valid() {
+    public virtual bool is_valid(bool and_useful) {
         return dtstamp != null;
     }
     
diff --git a/src/host/host-quick-create-event.vala b/src/host/host-quick-create-event.vala
index 9cdea9c..267a0b0 100644
--- a/src/host/host-quick-create-event.vala
+++ b/src/host/host-quick-create-event.vala
@@ -110,7 +110,7 @@ public class QuickCreateEvent : Gtk.Grid, Toolkit.Card {
             event);
         event = parser.event;
         
-        if (event.is_valid()) {
+        if (event.is_valid(true)) {
             create_event_async.begin(null);
         } else {
             // see note above about why the Deck jumps to Create/Update and then this Card is
diff --git a/src/tests/tests-quick-add.vala b/src/tests/tests-quick-add.vala
index 5ec8364..a1c398d 100644
--- a/src/tests/tests-quick-add.vala
+++ b/src/tests/tests-quick-add.vala
@@ -8,13 +8,14 @@ namespace California.Tests {
 
 private class QuickAdd : UnitTest.Harness {
     public QuickAdd() {
-        add_case("null", null_details);
+        add_case("null-details", null_details);
         add_case("blank", blank);
         add_case("punct", punct);
         add_case("summary", summary);
         add_case("summary-with-blanks", summary_with_blanks);
         add_case("summary-with-punct", summary_with_punct);
         add_case("summary-location", summary_location);
+        add_case("valid-no-summary", valid_no_summary);
         add_case("with-12hr-time", with_12hr_time);
         add_case("with-24hr-time", with_24hr_time);
         add_case("with-day-of-week", with_day_of_week);
@@ -34,6 +35,8 @@ private class QuickAdd : UnitTest.Harness {
         add_case("separate-pm", separate_pm);
         add_case("start-date-ordinal", start_date_ordinal);
         add_case("end-date-ordinal", end_date_ordinal);
+        add_case("simple-and", simple_and);
+        add_case("this-weekend", this_weekend);
     }
     
     protected override void setup() throws Error {
@@ -49,19 +52,19 @@ private class QuickAdd : UnitTest.Harness {
     private bool null_details() throws Error {
         Component.DetailsParser parser = new Component.DetailsParser(null, null);
         
-        return !parser.event.is_valid();
+        return !parser.event.is_valid(false);
     }
     
     private bool blank() throws Error {
         Component.DetailsParser parser = new Component.DetailsParser(" ", null);
         
-        return !parser.event.is_valid();
+        return !parser.event.is_valid(false);
     }
     
     private bool punct() throws Error {
         Component.DetailsParser parser = new Component.DetailsParser("&", null);
         
-        return !parser.event.is_valid()
+        return !parser.event.is_valid(false)
             && parser.event.summary == "&";
     }
     
@@ -101,6 +104,18 @@ private class QuickAdd : UnitTest.Harness {
             && parser.event.date_span == null;
     }
     
+    private bool valid_no_summary(out string? dump) throws Error {
+        Component.DetailsParser parser = new Component.DetailsParser("7pm to 9pm", null);
+        
+        dump = parser.event.source;
+        
+        // valid but not "useful"
+        return parser.event.is_valid(false)
+            && !parser.event.is_valid(true)
+            && California.String.is_empty(parser.event.summary)
+            && parser.event.exact_time_span != null;
+    }
+    
     private bool with_12hr_time() throws Error {
         return with_time(new Component.DetailsParser("dinner at 7pm with Alice", null));
     }
@@ -333,6 +348,32 @@ private class QuickAdd : UnitTest.Harness {
             && parser.event.date_span.start_date.equal_to(start)
             && parser.event.date_span.end_date.equal_to(end);
     }
+    
+    private bool simple_and(out string? dump) throws Error {
+        Component.DetailsParser parser = new Component.DetailsParser(
+            "Manga & Anime Festival Saturday and Sunday at Airport Hyatt, Shelbyville", null);
+        
+        dump = parser.event.source;
+        
+        return parser.event.summary == "Manga & Anime Festival at Airport Hyatt, Shelbyville"
+            && parser.event.location == "Airport Hyatt, Shelbyville"
+            && parser.event.is_all_day
+            && parser.event.date_span.start_date.day_of_week == Calendar.DayOfWeek.SAT
+            && parser.event.date_span.end_date.day_of_week == Calendar.DayOfWeek.SUN;
+    }
+    
+    private bool this_weekend(out string? dump) throws Error {
+        Component.DetailsParser parser = new Component.DetailsParser(
+            "Manga & Anime Festival this weekend at Airport Hyatt, Shelbyville", null);
+        
+        dump = parser.event.source;
+        
+        return parser.event.summary == "Manga & Anime Festival at Airport Hyatt, Shelbyville"
+            && parser.event.location == "Airport Hyatt, Shelbyville"
+            && parser.event.is_all_day
+            && parser.event.date_span.start_date.day_of_week == Calendar.DayOfWeek.SAT
+            && parser.event.date_span.end_date.day_of_week == Calendar.DayOfWeek.SUN;
+    }
 }
 
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]