[california] Deal with standalone punctuation in Quick Add details



commit cef0a3ee71704a94ec53b33341000b6a3fe27690
Author: Jim Nelson <jim yorba org>
Date:   Wed Jun 25 18:37:44 2014 -0700

    Deal with standalone punctuation in Quick Add details
    
    For example, "Alice & Bob".

 src/component/component-details-parser.vala |   16 +++++++++++++---
 src/tests/tests-quick-add.vala              |   18 ++++++++++++++++++
 2 files changed, 31 insertions(+), 3 deletions(-)
---
diff --git a/src/component/component-details-parser.vala b/src/component/component-details-parser.vala
index d7481eb..bf2db73 100644
--- a/src/component/component-details-parser.vala
+++ b/src/component/component-details-parser.vala
@@ -25,7 +25,7 @@ public class DetailsParser : BaseObject {
         
         public Token(string token) {
             original = token;
-            casefolded = from_string(token).filter(c => !c.ispunct()).to_string(c => c.to_string());
+            casefolded = from_string(token).filter(c => !c.ispunct()).to_string(c => c.to_string()) ?? "";
         }
         
         public bool equal_to(Token other) {
@@ -114,8 +114,10 @@ public class DetailsParser : BaseObject {
         // tokenize the string and arrange as a stack for the parser
         string[] tokenized = String.reduce_whitespace(this.details).split(" ");
         Gee.LinkedList<Token> list = new Gee.LinkedList<Token>();
-        foreach (string token in tokenized)
-            list.add(new Token(token));
+        foreach (string token in tokenized) {
+            if (!String.is_empty(token))
+                list.add(new Token(token));
+        }
         
         stack = new Collection.LookaheadStack<Token>(list);
         
@@ -128,6 +130,14 @@ public class DetailsParser : BaseObject {
             if (token == null)
                 break;
             
+            // because whitespace and punctuation is stripped from the original token, it's possible
+            // for the casefolded token to be empty
+            if (String.is_empty(token.casefolded)) {
+                add_text(token);
+                
+                continue;
+            }
+            
             // mark the stack branch for each parsing branch so if it fails the state can be
             // restored and the next branch's read-ahead gets a chance; don't restore on success
             // as each method is responsible for consuming all tokens it needs to complete its work
diff --git a/src/tests/tests-quick-add.vala b/src/tests/tests-quick-add.vala
index c01ca84..5ec8364 100644
--- a/src/tests/tests-quick-add.vala
+++ b/src/tests/tests-quick-add.vala
@@ -10,8 +10,10 @@ private class QuickAdd : UnitTest.Harness {
     public QuickAdd() {
         add_case("null", 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("with-12hr-time", with_12hr_time);
         add_case("with-24hr-time", with_24hr_time);
@@ -56,6 +58,13 @@ private class QuickAdd : UnitTest.Harness {
         return !parser.event.is_valid();
     }
     
+    private bool punct() throws Error {
+        Component.DetailsParser parser = new Component.DetailsParser("&", null);
+        
+        return !parser.event.is_valid()
+            && parser.event.summary == "&";
+    }
+    
     private bool summary() throws Error {
         Component.DetailsParser parser = new Component.DetailsParser("meet with Alice", null);
         
@@ -74,6 +83,15 @@ private class QuickAdd : UnitTest.Harness {
             && parser.event.date_span == null;
     }
     
+    private bool summary_with_punct() throws Error {
+        Component.DetailsParser parser = new Component.DetailsParser("meet with Alice & Bob", null);
+        
+        return parser.event.summary == "meet with Alice & Bob"
+            && parser.event.location == null
+            && parser.event.exact_time_span == null
+            && parser.event.date_span == null;
+    }
+    
     private bool summary_location() throws Error {
         Component.DetailsParser parser = new Component.DetailsParser("meet with Alice at Bob's", null);
         


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