You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by rd...@apache.org on 2008/02/28 00:09:09 UTC

svn commit: r631770 - in /james/server/trunk/imap-codec-library/src: main/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParser.java test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeyTest.java

Author: rdonkin
Date: Wed Feb 27 15:09:07 2008
New Revision: 631770

URL: http://svn.apache.org/viewvc?rev=631770&view=rev
Log:
Most of the base parsing for search done now. The difficult stuff's still remaining but the quantity's done.

Modified:
    james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParser.java
    james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeyTest.java

Modified: james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParser.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParser.java?rev=631770&r1=631769&r2=631770&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParser.java (original)
+++ james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParser.java Wed Feb 27 15:09:07 2008
@@ -18,9 +18,6 @@
  ****************************************************************/
 package org.apache.james.imapserver.codec.decode.imap4rev1;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-
 import org.apache.james.api.imap.ImapCommand;
 import org.apache.james.api.imap.ImapMessage;
 import org.apache.james.api.imap.ProtocolException;
@@ -31,45 +28,7 @@
 import org.apache.james.imapserver.codec.decode.InitialisableCommandFactory;
 
 class SearchCommandParser extends AbstractUidCommandParser implements InitialisableCommandFactory
-{
-    public static final void main(String[] args) throws Exception {
-        final byte[] mixed = "BEforE 1-Jan-2000".getBytes("US-ASCII");
-        final byte[] allSmalls = "before 1-Jan-2000".getBytes("US-ASCII");
-        final byte[] allCaps = "BEFORE 1-Jan-2000".getBytes("US-ASCII");
-        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        SearchCommandParser parser = new SearchCommandParser();
-        long start  = System.currentTimeMillis();
-        long i = 0;
-        ByteArrayInputStream bais = new ByteArrayInputStream(allCaps);
-        while (i++ < 1000000) {
-                bais.reset();
-                ImapRequestLineReader request = new ImapRequestLineReader(
-                        bais, 
-                        baos);
-                parser.searchKey(request);
-        }
-        i = 0;
-        bais = new ByteArrayInputStream(allSmalls);
-        while (i++ < 1000000) {
-            bais.reset();
-            ImapRequestLineReader request = new ImapRequestLineReader(
-                    bais, 
-                    baos);
-            parser.searchKey(request);
-        }
-        i = 0;
-        bais = new ByteArrayInputStream(mixed);
-        while (i++ < 1000000) {
-            bais.reset();
-            ImapRequestLineReader request = new ImapRequestLineReader(
-                    bais, 
-                    baos);
-            parser.searchKey(request);
-        }
-        long end = System.currentTimeMillis();
-        System.out.println(end - start);
-    }
-    
+{   
     public SearchCommandParser() {
     }
 
@@ -103,6 +62,12 @@
             case 'M': throw new ProtocolException("Unknown search key");
             case 'N': return n(request);
             case 'O': return o(request);
+            case 'P': throw new ProtocolException("Unknown search key");
+            case 'Q': throw new ProtocolException("Unknown search key");
+            case 'R': return recent(request);
+            case 'S': return s(request);
+            case 'T': return t(request);
+            case 'U': return u(request);
             default:
                 throw new ProtocolException("Unknown search key");
         }
@@ -122,6 +87,90 @@
         result = SearchKey.buildCc(value);
         return result;
     }
+
+    private SearchKey u(ImapRequestLineReader request) throws ProtocolException {
+        final int next = consumeAndCap(request);
+        switch (next) {
+            case 'N': return un(request);
+            default:
+                throw new ProtocolException("Unknown search key");
+        }
+    }
+    
+    private SearchKey un(ImapRequestLineReader request) throws ProtocolException {
+        final int next = consumeAndCap(request);
+        switch (next) {
+            case 'A': return unanswered(request);
+            case 'D': return und(request);
+            case 'F': return unflagged(request);
+            case 'K': return unkeyword(request);
+            case 'S': return unseen(request);
+            default:
+                throw new ProtocolException("Unknown search key");
+        }
+    }
+    
+    private SearchKey und(ImapRequestLineReader request) throws ProtocolException {
+        final int next = consumeAndCap(request);
+        switch (next) {
+            case 'E': return undeleted(request);
+            case 'R': return undraft(request);
+            default:
+                throw new ProtocolException("Unknown search key");
+        }
+    }
+    
+    private SearchKey t(ImapRequestLineReader request) throws ProtocolException {
+        final int next = consumeAndCap(request);
+        switch (next) {
+            case 'E': return text(request);
+            case 'O': return to(request);
+            default:
+                throw new ProtocolException("Unknown search key");
+        }
+    }
+    
+    private SearchKey s(ImapRequestLineReader request) throws ProtocolException {
+        final int next = consumeAndCap(request);
+        switch (next) {
+            case 'E': return se(request);
+            case 'I': return since(request);
+            case 'M': return smaller(request);
+            case 'U': return subject(request);
+            default:
+                throw new ProtocolException("Unknown search key");
+        }
+    }
+    
+    private SearchKey se(ImapRequestLineReader request) throws ProtocolException {
+        final int next = consumeAndCap(request);
+        switch (next) {
+            case 'E': return seen(request);
+            case 'N': return sen(request);
+            default:
+                throw new ProtocolException("Unknown search key");
+        }
+    }
+    
+    private SearchKey sen(ImapRequestLineReader request) throws ProtocolException {
+        final int next = consumeAndCap(request);
+        switch (next) {
+            case 'T': return sent(request);
+            default:
+                throw new ProtocolException("Unknown search key");
+        }
+    }
+    
+    private SearchKey sent(ImapRequestLineReader request) throws ProtocolException {
+        final int next = consumeAndCap(request);
+        switch (next) {
+            case 'B': return sentBefore(request);
+            case 'O': return sentOn(request);
+            case 'S': return sentSince(request);
+            default:
+                throw new ProtocolException("Unknown search key");
+        }
+    }
     
     private SearchKey o(ImapRequestLineReader request) throws ProtocolException {
         final int next = consumeAndCap(request);
@@ -176,6 +225,21 @@
         return result;
     }
     
+    private SearchKey unkeyword(ImapRequestLineReader request) throws ProtocolException {
+        final SearchKey result;
+        nextIsE(request);
+        nextIsY(request);
+        nextIsW(request);
+        nextIsO(request);
+        nextIsR(request);
+        nextIsD(request);
+        nextIsSpace(request);
+        final String value = atom(request);
+        result = SearchKey.buildUnkeyword(value);
+        return result;
+    }
+    
+    
     private SearchKey header(ImapRequestLineReader request) throws ProtocolException {
         final SearchKey result;
         nextIsE(request);
@@ -204,6 +268,19 @@
         return result;
     }
     
+    private SearchKey smaller(ImapRequestLineReader request) throws ProtocolException {
+        final SearchKey result;
+        nextIsA(request);
+        nextIsL(request);
+        nextIsL(request);
+        nextIsE(request);
+        nextIsR(request);
+        nextIsSpace(request);
+        final long value = number(request);
+        result = SearchKey.buildSmaller(value);
+        return result;
+    }
+    
     private SearchKey from(ImapRequestLineReader request) throws ProtocolException {
         final SearchKey result;
         nextIsO(request);
@@ -225,6 +302,60 @@
         return result;
     }
     
+    private SearchKey unseen(ImapRequestLineReader request) throws ProtocolException {
+        final SearchKey result;
+        nextIsE(request);
+        nextIsE(request);
+        nextIsN(request);
+        result = SearchKey.buildUnseen();
+        return result;
+    }
+    
+    private SearchKey undraft(ImapRequestLineReader request) throws ProtocolException {
+        final SearchKey result;
+        nextIsA(request);
+        nextIsF(request);
+        nextIsT(request);
+        result = SearchKey.buildUndraft();
+        return result;
+    }
+    
+    private SearchKey undeleted(ImapRequestLineReader request) throws ProtocolException {
+        final SearchKey result;
+        nextIsL(request);
+        nextIsE(request);
+        nextIsT(request);
+        nextIsE(request);
+        nextIsD(request);
+        result = SearchKey.buildUndeleted();
+        return result;
+    }
+    
+    private SearchKey unflagged(ImapRequestLineReader request) throws ProtocolException {
+        final SearchKey result;
+        nextIsL(request);
+        nextIsA(request);
+        nextIsG(request);
+        nextIsG(request);
+        nextIsE(request);
+        nextIsD(request);
+        result = SearchKey.buildUnflagged();
+        return result;
+    }
+    
+    private SearchKey unanswered(ImapRequestLineReader request) throws ProtocolException {
+        final SearchKey result;
+        nextIsN(request);
+        nextIsS(request);
+        nextIsW(request);
+        nextIsE(request);
+        nextIsR(request);
+        nextIsE(request);
+        nextIsD(request);
+        result = SearchKey.buildUnanswered();
+        return result;
+    }
+    
     private SearchKey old(ImapRequestLineReader request) throws ProtocolException {
         final SearchKey result;
         nextIsD(request);
@@ -239,6 +370,24 @@
         return result;
     }
     
+    private SearchKey recent(ImapRequestLineReader request) throws ProtocolException {
+        final SearchKey result;
+        nextIsE(request);
+        nextIsC(request);
+        nextIsE(request);
+        nextIsN(request);
+        nextIsT(request);
+        result = SearchKey.buildRecent();
+        return result;
+    }
+    
+    private SearchKey seen(ImapRequestLineReader request) throws ProtocolException {
+        final SearchKey result;
+        nextIsN(request);
+        result = SearchKey.buildSeen();
+        return result;
+    }
+    
     private SearchKey draft(ImapRequestLineReader request) throws ProtocolException {
         final SearchKey result;
         nextIsA(request);
@@ -288,6 +437,51 @@
         return result;
     }
     
+    private SearchKey sentBefore(ImapRequestLineReader request) throws ProtocolException {
+        final SearchKey result;
+        nextIsE(request);
+        nextIsF(request);
+        nextIsO(request);
+        nextIsR(request);
+        nextIsE(request);
+        nextIsSpace(request);
+        final DayMonthYear value = date(request);
+        result = SearchKey.buildSentBefore(value);
+        return result;
+    }
+    
+    private SearchKey sentSince(ImapRequestLineReader request) throws ProtocolException {
+        final SearchKey result;
+        nextIsI(request);
+        nextIsN(request);
+        nextIsC(request);
+        nextIsE(request);
+        nextIsSpace(request);
+        final DayMonthYear value = date(request);
+        result = SearchKey.buildSentSince(value);
+        return result;
+    }
+    
+    private SearchKey since(ImapRequestLineReader request) throws ProtocolException {
+        final SearchKey result;
+        nextIsN(request);
+        nextIsC(request);
+        nextIsE(request);
+        nextIsSpace(request);
+        final DayMonthYear value = date(request);
+        result = SearchKey.buildSince(value);
+        return result;
+    }
+    
+    private SearchKey sentOn(ImapRequestLineReader request) throws ProtocolException {
+        final SearchKey result;
+        nextIsN(request);
+        nextIsSpace(request);
+        final DayMonthYear value = date(request);
+        result = SearchKey.buildSentOn(value);
+        return result;
+    }
+    
     private SearchKey before(ImapRequestLineReader request) throws ProtocolException {
         final SearchKey result;
         nextIsF(request);
@@ -308,6 +502,37 @@
         result = SearchKey.buildBcc(value);
         return result;
     }
+    
+    private SearchKey text(ImapRequestLineReader request) throws ProtocolException {
+        final SearchKey result;
+        nextIsX(request);
+        nextIsT(request);
+        nextIsSpace(request);
+        final String value = astring(request);
+        result = SearchKey.buildText(value);
+        return result;
+    }
+    
+    private SearchKey to(ImapRequestLineReader request) throws ProtocolException {
+        final SearchKey result;
+        nextIsSpace(request);
+        final String value = astring(request);
+        result = SearchKey.buildTo(value);
+        return result;
+    }
+    
+    private SearchKey subject(ImapRequestLineReader request) throws ProtocolException {
+        final SearchKey result;
+        nextIsB(request);
+        nextIsJ(request);
+        nextIsE(request);
+        nextIsC(request);
+        nextIsT(request);
+        nextIsSpace(request);
+        final String value = astring(request);
+        result = SearchKey.buildSubject(value);
+        return result;
+    }
 
     private SearchKey a(ImapRequestLineReader request) throws ProtocolException {
         final int next = consumeAndCap(request);
@@ -346,103 +571,88 @@
     }
     
     private void nextIsG( ImapRequestLineReader request ) throws ProtocolException {
-        final char next = request.consume();
-        if (next != 'G' && next != 'g') {
-            throw new ProtocolException("Unknown search key");
-        }
+        nextIs(request, 'G', 'g');
     }
     
     private void nextIsM( ImapRequestLineReader request ) throws ProtocolException {
-        final char next = request.consume();
-        if (next != 'M' && next != 'm') {
-            throw new ProtocolException("Unknown search key");
-        }
+        nextIs(request, 'M', 'm');
+    }
+    
+    private void nextIsI( ImapRequestLineReader request ) throws ProtocolException {
+        nextIs(request, 'I', 'i');
+    }
+    
+    private void nextIsN( ImapRequestLineReader request ) throws ProtocolException {
+        nextIs(request, 'N', 'n');
     }
     
     private void nextIsA( ImapRequestLineReader request ) throws ProtocolException {
-        final char next = request.consume();
-        if (next != 'A' && next != 'a') {
-            throw new ProtocolException("Unknown search key");
-        }
+        nextIs(request, 'A', 'a');
     }
     
     private void nextIsT( ImapRequestLineReader request ) throws ProtocolException {
-        final char next = request.consume();
-        if (next != 'T' && next != 't') {
-            throw new ProtocolException("Unknown search key");
-        }
+        nextIs(request, 'T', 't');
     }
     
     private void nextIsY( ImapRequestLineReader request ) throws ProtocolException {
-        final char next = request.consume();
-        if (next != 'Y' && next != 'y') {
-            throw new ProtocolException("Unknown search key");
-        }
+        nextIs(request, 'Y','y');
+    }
+    
+    private void nextIsX( ImapRequestLineReader request ) throws ProtocolException {
+        nextIs(request, 'X', 'x');
     }
     
     private void nextIsO( ImapRequestLineReader request ) throws ProtocolException {
-        final char next = request.consume();
-        if (next != 'O' && next != 'o') {
-            throw new ProtocolException("Unknown search key");
-        }
+        nextIs(request, 'O', 'o');
     }
     
     private void nextIsF( ImapRequestLineReader request ) throws ProtocolException {
-        final char next = request.consume();
-        if (next != 'F' && next != 'f') {
-            throw new ProtocolException("Unknown search key");
-        }
+        nextIs(request, 'F', 'f');
+    }
+    
+    private void nextIsJ( ImapRequestLineReader request ) throws ProtocolException {
+        nextIs(request, 'J', 'j');
     }
     
     private void nextIsC( ImapRequestLineReader request ) throws ProtocolException {
-        final char next = request.consume();
-        if (next != 'C' && next != 'c') {
-            throw new ProtocolException("Unknown search key");
-        }
+        nextIs(request, 'C', 'c');
     }
     
     private void nextIsD( ImapRequestLineReader request ) throws ProtocolException {
-        final char next = request.consume();
-        if (next != 'D' && next != 'd') {
-            throw new ProtocolException("Unknown search key");
-        }
+        nextIs(request, 'D', 'd');
+    }
+    
+    private void nextIsB( ImapRequestLineReader request ) throws ProtocolException {
+        nextIs(request, 'B', 'b');
     }
     
     private void nextIsR( ImapRequestLineReader request ) throws ProtocolException {
-        final char next = request.consume();
-        if (next != 'R' && next != 'r') {
-            throw new ProtocolException("Unknown search key");
-        }
+        nextIs(request, 'R', 'r');
     }
     
     private void nextIsE( ImapRequestLineReader request ) throws ProtocolException {
-        final char next = request.consume();
-        if (next != 'E' && next != 'e') {
-            throw new ProtocolException("Unknown search key");
-        }
+        nextIs(request, 'E', 'e');
     }
     
     private void nextIsW( ImapRequestLineReader request ) throws ProtocolException {
-        final char next = request.consume();
-        if (next != 'W' && next != 'w') {
-            throw new ProtocolException("Unknown search key");
-        }
+        nextIs(request, 'W', 'w');
     }
     
     private void nextIsS( ImapRequestLineReader request ) throws ProtocolException {
-        final char next = request.consume();
-        if (next != 'S' && next != 's') {
-            throw new ProtocolException("Unknown search key");
-        }
+        nextIs(request, 'S', 's');
     }
     
     private void nextIsL( ImapRequestLineReader request ) throws ProtocolException {
+        nextIs(request, 'L', 'l');
+    }
+
+    private void nextIs( ImapRequestLineReader request, final char upper, final char lower ) throws ProtocolException {
         final char next = request.consume();
-        if (next != 'L' && next != 'l') {
+        if (next != upper && next != lower) {
             throw new ProtocolException("Unknown search key");
         }
     }
-
+    
     protected ImapMessage decode(ImapCommand command, ImapRequestLineReader request, String tag, boolean useUids) throws ProtocolException {
         // Parse the search term from the request
         request.nextWordChar();

Modified: james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeyTest.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeyTest.java?rev=631770&r1=631769&r2=631770&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeyTest.java (original)
+++ james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeyTest.java Wed Feb 27 15:09:07 2008
@@ -117,6 +117,85 @@
         checkInvalid("on 1-Jan-\r\n", key);
     }
     
+    public void testShouldParseSentBefore() throws Exception {
+        SearchKey key = SearchKey.buildSentBefore(DATE);
+        checkValid("SENTBEFORE 1-Jan-2000\r\n", key);
+        checkValid("sentbefore 1-Jan-2000\r\n", key);
+        checkValid("SentBefore 1-Jan-2000\r\n", key);
+        checkInvalid("s\r\n", key);
+        checkInvalid("se\r\n", key);
+        checkInvalid("sent\r\n", key);
+        checkInvalid("sentb \r\n", key);
+        checkInvalid("sentbe \r\n", key);
+        checkInvalid("sentbef \r\n", key);
+        checkInvalid("sentbefo \r\n", key);
+        checkInvalid("sentbefor \r\n", key);
+        checkInvalid("sentbefore \r\n", key);
+        checkInvalid("sentbefore 1\r\n", key);
+        checkInvalid("sentbefore 1-\r\n", key);
+        checkInvalid("sentbefore 1-J\r\n", key);
+        checkInvalid("sentbefore 1-Ja\r\n", key);
+        checkInvalid("sentbefore 1-Jan\r\n", key);
+        checkInvalid("sentbefore 1-Jan-\r\n", key);
+    }
+    
+    public void testShouldParseSentOn() throws Exception {
+        SearchKey key = SearchKey.buildSentOn(DATE);
+        checkValid("SENTON 1-Jan-2000\r\n", key);
+        checkValid("senton 1-Jan-2000\r\n", key);
+        checkValid("SentOn 1-Jan-2000\r\n", key);
+        checkInvalid("s\r\n", key);
+        checkInvalid("se\r\n", key);
+        checkInvalid("sent\r\n", key);
+        checkInvalid("sento \r\n", key);
+        checkInvalid("senton \r\n", key);
+        checkInvalid("senton 1\r\n", key);
+        checkInvalid("senton 1-\r\n", key);
+        checkInvalid("senton 1-J\r\n", key);
+        checkInvalid("senton 1-Ja\r\n", key);
+        checkInvalid("senton 1-Jan\r\n", key);
+        checkInvalid("senton 1-Jan-\r\n", key);
+    }
+    
+    public void testShouldParseSentSince() throws Exception {
+        SearchKey key = SearchKey.buildSentSince(DATE);
+        checkValid("SENTSINCE 1-Jan-2000\r\n", key);
+        checkValid("sentsince 1-Jan-2000\r\n", key);
+        checkValid("SentSince 1-Jan-2000\r\n", key);
+        checkInvalid("s\r\n", key);
+        checkInvalid("se\r\n", key);
+        checkInvalid("sent\r\n", key);
+        checkInvalid("sents \r\n", key);
+        checkInvalid("sentsi \r\n", key);
+        checkInvalid("sentsin \r\n", key);
+        checkInvalid("sentsinc \r\n", key);
+        checkInvalid("sentsince \r\n", key);
+        checkInvalid("sentsince 1\r\n", key);
+        checkInvalid("sentsince 1-\r\n", key);
+        checkInvalid("sentsince 1-J\r\n", key);
+        checkInvalid("sentsince 1-Ja\r\n", key);
+        checkInvalid("sentsince 1-Jan\r\n", key);
+        checkInvalid("sentsince 1-Jan-\r\n", key);
+    }
+    
+    public void testShouldParseSince() throws Exception {
+        SearchKey key = SearchKey.buildSince(DATE);
+        checkValid("SINCE 1-Jan-2000\r\n", key);
+        checkValid("since 1-Jan-2000\r\n", key);
+        checkValid("Since 1-Jan-2000\r\n", key);
+        checkInvalid("s \r\n", key);
+        checkInvalid("si \r\n", key);
+        checkInvalid("sin \r\n", key);
+        checkInvalid("sinc \r\n", key);
+        checkInvalid("since \r\n", key);
+        checkInvalid("since 1\r\n", key);
+        checkInvalid("since 1-\r\n", key);
+        checkInvalid("since 1-J\r\n", key);
+        checkInvalid("since 1-Ja\r\n", key);
+        checkInvalid("since 1-Jan\r\n", key);
+        checkInvalid("since 1-Jan-\r\n", key);
+    }
+    
     public void testShouldParseBefore() throws Exception {
         SearchKey key = SearchKey.buildBefore(DATE);
         checkValid("BEFORE 1-Jan-2000\r\n", key);
@@ -154,6 +233,52 @@
         checkInvalid("Bodym\r\n", key);   
     }
     
+    public void testShouldParseTo() throws Exception {
+        SearchKey key = SearchKey.buildTo("AnAddress");
+        checkValid("TO AnAddress\r\n", key);
+        checkValid("TO \"AnAddress\"\r\n", key);
+        checkValid("to AnAddress\r\n", key);
+        checkValid("to \"AnAddress\"\r\n", key);
+        checkValid("To AnAddress\r\n", key);
+        checkValid("To \"AnAddress\"\r\n", key);
+        checkInvalid("t\r\n", key);
+        checkInvalid("to\r\n", key);
+        checkInvalid("too\r\n", key);
+        checkInvalid("to \r\n", key);
+    }
+    
+    public void testShouldParseText() throws Exception {
+        SearchKey key = SearchKey.buildText("SomeText");
+        checkValid("TEXT SomeText\r\n", key);
+        checkValid("TEXT \"SomeText\"\r\n", key);
+        checkValid("text SomeText\r\n", key);
+        checkValid("text \"SomeText\"\r\n", key);
+        checkValid("Text SomeText\r\n", key);
+        checkValid("Text \"SomeText\"\r\n", key);
+        checkInvalid("t\r\n", key);
+        checkInvalid("te\r\n", key);
+        checkInvalid("tex\r\n", key);
+        checkInvalid("text\r\n", key);
+        checkInvalid("text \r\n", key);
+    }
+    
+    public void testShouldParseSubject() throws Exception {
+        SearchKey key = SearchKey.buildSubject("ASubject");
+        checkValid("SUBJECT ASubject\r\n", key);
+        checkValid("SUBJECT \"ASubject\"\r\n", key);
+        checkValid("subject ASubject\r\n", key);
+        checkValid("subject \"ASubject\"\r\n", key);
+        checkValid("Subject ASubject\r\n", key);
+        checkValid("Subject \"ASubject\"\r\n", key);
+        checkInvalid("s\r\n", key);
+        checkInvalid("su\r\n", key);
+        checkInvalid("sub\r\n", key);
+        checkInvalid("subj\r\n", key);
+        checkInvalid("subje\r\n", key);
+        checkInvalid("subjec\r\n", key);
+        checkInvalid("subject\r\n", key);
+        checkInvalid("subject \r\n", key);
+    }
     
     public void testShouldParseCc() throws Exception {
         SearchKey key = SearchKey.buildCc("SomeText");
@@ -200,6 +325,26 @@
         checkInvalid("keyword \r\n", key);
     }
     
+    public void testShouldParseUnKeyword() throws Exception {
+        SearchKey key = SearchKey.buildUnkeyword("AFlag");
+        checkValid("UNKEYWORD AFlag\r\n", key);
+        checkInvalid("UNKEYWORD \"AFlag\"\r\n", key);
+        checkValid("unkeyword AFlag\r\n", key);
+        checkInvalid("unkeyword \"AFlag\"\r\n", key);
+        checkValid("UnKEYword AFlag\r\n", key);
+        checkInvalid("UnKEYword \"AFlag\"\r\n", key);
+        checkInvalid("u\r\n", key);
+        checkInvalid("un\r\n", key);
+        checkInvalid("unk\r\n", key);
+        checkInvalid("unke\r\n", key);
+        checkInvalid("unkey\r\n", key);
+        checkInvalid("unkeyw\r\n", key);
+        checkInvalid("unkeywo\r\n", key);
+        checkInvalid("unkeywor\r\n", key);
+        checkInvalid("unkeywordi\r\n", key);
+        checkInvalid("unkeyword \r\n", key);
+    }
+    
 
     public void testShouldParseHeader() throws Exception {
         SearchKey key = SearchKey.buildHeader("Field", "Value");
@@ -245,6 +390,84 @@
         checkInvalid("ee\r\n", key);
     }
     
+    public void testGShouldBeInvalid() throws Exception {
+        SearchKey key = SearchKey.buildDeleted();
+        checkInvalid("g\r\n", key);
+        checkInvalid("G\r\n", key);
+    }
+    
+    public void testIShouldBeInvalid() throws Exception {
+        SearchKey key = SearchKey.buildDeleted();
+        checkInvalid("i\r\n", key);
+        checkInvalid("I\r\n", key);
+    }
+    
+    public void testJShouldBeInvalid() throws Exception {
+        SearchKey key = SearchKey.buildDeleted();
+        checkInvalid("j\r\n", key);
+        checkInvalid("J\r\n", key);
+    }
+    
+    public void testMShouldBeInvalid() throws Exception {
+        SearchKey key = SearchKey.buildDeleted();
+        checkInvalid("m\r\n", key);
+        checkInvalid("M\r\n", key);
+    }
+    
+    public void testPShouldBeInvalid() throws Exception {
+        SearchKey key = SearchKey.buildDeleted();
+        checkInvalid("p\r\n", key);
+        checkInvalid("Pp\r\n", key);
+    }
+    
+    public void testQShouldBeInvalid() throws Exception {
+        SearchKey key = SearchKey.buildDeleted();
+        checkInvalid("q\r\n", key);
+        checkInvalid("Qq\r\n", key);
+    }
+    
+    public void testWShouldBeInvalid() throws Exception {
+        SearchKey key = SearchKey.buildDeleted();
+        checkInvalid("w\r\n", key);
+        checkInvalid("ww\r\n", key);
+    }
+    
+    public void testVShouldBeInvalid() throws Exception {
+        SearchKey key = SearchKey.buildDeleted();
+        checkInvalid("v\r\n", key);
+        checkInvalid("vv\r\n", key);
+    }
+    
+    public void testXShouldBeInvalid() throws Exception {
+        SearchKey key = SearchKey.buildDeleted();
+        checkInvalid("x\r\n", key);
+        checkInvalid("xx\r\n", key);
+    }
+    
+    public void testYShouldBeInvalid() throws Exception {
+        SearchKey key = SearchKey.buildDeleted();
+        checkInvalid("y\r\n", key);
+        checkInvalid("yy\r\n", key);
+    }
+    
+    public void testZShouldBeInvalid() throws Exception {
+        SearchKey key = SearchKey.buildDeleted();
+        checkInvalid("z\r\n", key);
+        checkInvalid("zz\r\n", key);
+    }
+    
+    public void testShouldParseRecent() throws Exception {
+        SearchKey key = SearchKey.buildRecent();
+        checkValid("RECENT\r\n", key);
+        checkValid("recent\r\n", key);
+        checkValid("reCENt\r\n", key);
+        checkInvalid("r\r\n", key);
+        checkInvalid("re\r\n", key);
+        checkInvalid("rec\r\n", key);
+        checkInvalid("rece\r\n", key);
+        checkInvalid("recen\r\n", key);
+    }
+    
     public void testShouldParseDraft() throws Exception {
         SearchKey key = SearchKey.buildDraft();
         checkValid("DRAFT\r\n", key);
@@ -256,6 +479,87 @@
         checkInvalid("DRAF\r\n", key);
     }
     
+    public void testShouldParseUnanswered() throws Exception {
+        SearchKey key = SearchKey.buildUnanswered();
+        checkValid("UNANSWERED\r\n", key);
+        checkValid("unanswered\r\n", key);
+        checkValid("UnAnswered\r\n", key);
+        checkInvalid("u\r\n", key);
+        checkInvalid("un\r\n", key);
+        checkInvalid("una\r\n", key);
+        checkInvalid("unan\r\n", key);
+        checkInvalid("unans\r\n", key);
+        checkInvalid("unansw\r\n", key);
+        checkInvalid("unanswe\r\n", key);
+        checkInvalid("unanswer\r\n", key);
+        checkInvalid("unanswere\r\n", key);
+    }
+    
+    public void testShouldParseUndeleted() throws Exception {
+        SearchKey key = SearchKey.buildUndeleted();
+        checkValid("UNDELETED\r\n", key);
+        checkValid("undeleted\r\n", key);
+        checkValid("UnDeleted\r\n", key);
+        checkInvalid("u\r\n", key);
+        checkInvalid("un\r\n", key);
+        checkInvalid("und\r\n", key);
+        checkInvalid("unde\r\n", key);
+        checkInvalid("undel\r\n", key);
+        checkInvalid("undele\r\n", key);
+        checkInvalid("undelet\r\n", key);
+        checkInvalid("undelete\r\n", key);
+    }
+    
+    public void testShouldParseUnseen() throws Exception {
+        SearchKey key = SearchKey.buildUnseen();
+        checkValid("UNSEEN\r\n", key);
+        checkValid("unseen\r\n", key);
+        checkValid("UnSeen\r\n", key);
+        checkInvalid("u\r\n", key);
+        checkInvalid("un\r\n", key);
+        checkInvalid("uns\r\n", key);
+        checkInvalid("unse\r\n", key);
+        checkInvalid("unsee\r\n", key);
+    }
+    
+    public void testShouldParseUndraft() throws Exception {
+        SearchKey key = SearchKey.buildUndraft();
+        checkValid("UNDRAFT\r\n", key);
+        checkValid("undraft\r\n", key);
+        checkValid("UnDraft\r\n", key);
+        checkInvalid("u\r\n", key);
+        checkInvalid("un\r\n", key);
+        checkInvalid("und\r\n", key);
+        checkInvalid("undr\r\n", key);
+        checkInvalid("undra\r\n", key);
+        checkInvalid("undraf\r\n", key);
+    }
+    
+    public void testShouldParseUnflagged() throws Exception {
+        SearchKey key = SearchKey.buildUnflagged();
+        checkValid("UNFLAGGED\r\n", key);
+        checkValid("unflagged\r\n", key);
+        checkValid("UnFlagged\r\n", key);
+        checkInvalid("u\r\n", key);
+        checkInvalid("un\r\n", key);
+        checkInvalid("unf\r\n", key);
+        checkInvalid("unfl\r\n", key);
+        checkInvalid("unfla\r\n", key);
+        checkInvalid("unflag\r\n", key);
+        checkInvalid("unflagg\r\n", key);
+        checkInvalid("unflagge\r\n", key);
+    }
+    
+    public void testShouldParseSeen() throws Exception {
+        SearchKey key = SearchKey.buildSeen();
+        checkValid("SEEN\r\n", key);
+        checkValid("seen\r\n", key);
+        checkValid("SEen\r\n", key);
+        checkInvalid("s\r\n", key);
+        checkInvalid("se\r\n", key);
+        checkInvalid("see\r\n", key);
+    }
+    
     public void testShouldParseNew() throws Exception {
         SearchKey key = SearchKey.buildNew();
         checkValid("NEW\r\n", key);
@@ -289,12 +593,26 @@
         checkInvalid("FLAGGE\r\n", key);
         checkInvalid("FLoas\r\n", key);
     }
-    
 
+    public void testShouldParseSmaller() throws Exception {
+        SearchKey key = SearchKey.buildSmaller(1729);
+        checkValid("SMALLER 1729\r\n", key);
+        checkValid("smaller 1729\r\n", key);
+        checkValid("SMaller 1729\r\n", key);
+        checkInvalid("s\r\n", key);
+        checkInvalid("sm\r\n", key);
+        checkInvalid("sma\r\n", key);
+        checkInvalid("smal\r\n", key);
+        checkInvalid("small\r\n", key);
+        checkInvalid("smalle\r\n", key);
+        checkInvalid("smaller \r\n", key);
+        checkInvalid("smaller peach\r\n", key);
+     }
+    
     public void testShouldParseLarger() throws Exception {
         SearchKey key = SearchKey.buildLarger(1234);
         checkValid("LARGER 1234\r\n", key);
-        checkValid("larger 1234\r\n", key);
+        checkValid("lArGEr 1234\r\n", key);
         checkValid("larger 1234\r\n", key);
         checkInvalid("l\r\n", key);
         checkInvalid("la\r\n", key);



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org