--- /dev/null
+Return-Path: <sojkam1@fel.cvut.cz>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+ by olra.theworths.org (Postfix) with ESMTP id 32F7342D28D\r
+ for <notmuch@notmuchmail.org>; Sun, 23 Jan 2011 03:48:08 -0800 (PST)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: 0\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none]\r
+ autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+ by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+ with ESMTP id qzh4m-zf4cdL for <notmuch@notmuchmail.org>;\r
+ Sun, 23 Jan 2011 03:48:06 -0800 (PST)\r
+Received: from mail.loccal.net (gw.loccal.net [94.142.235.206])\r
+ by olra.theworths.org (Postfix) with ESMTP id C6B1642D280\r
+ for <notmuch@notmuchmail.org>; Sun, 23 Jan 2011 03:48:02 -0800 (PST)\r
+Received: from localhost (localhost [127.0.0.1])\r
+ by mail.loccal.net (Postfix) with ESMTP id E43C11043A;\r
+ Sun, 23 Jan 2011 13:01:17 +0100 (CET)\r
+X-Virus-Scanned: amavisd-new at loccal.net\r
+Received: from mail.loccal.net ([127.0.0.1])\r
+ by localhost (mail.loccal.net [127.0.0.1]) (amavisd-new, port 10024)\r
+ with LMTP id N48jDBcPsm-s; Sun, 23 Jan 2011 13:01:10 +0100 (CET)\r
+Received: from steelpick.2x.cz (unknown [10.21.129.4])\r
+ by mail.loccal.net (Postfix) with ESMTPS id 9DB5B1BDAF;\r
+ Sun, 23 Jan 2011 13:00:54 +0100 (CET)\r
+Received: from wsh by steelpick.2x.cz with local (Exim 4.72)\r
+ (envelope-from <sojkam1@fel.cvut.cz>)\r
+ id 1PgyPu-0005i8-RD; Sun, 23 Jan 2011 12:47:34 +0100\r
+From: Michal Sojka <sojkam1@fel.cvut.cz>\r
+To: notmuch@notmuchmail.org\r
+Subject: [PATCH 4/4] Add first date parser tests\r
+Date: Sun, 23 Jan 2011 12:47:27 +0100\r
+Message-Id: <1295783247-21900-5-git-send-email-sojkam1@fel.cvut.cz>\r
+X-Mailer: git-send-email 1.7.2.3\r
+In-Reply-To: <1295783247-21900-1-git-send-email-sojkam1@fel.cvut.cz>\r
+References: <1295783247-21900-1-git-send-email-sojkam1@fel.cvut.cz>\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+ <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Sun, 23 Jan 2011 11:48:08 -0000\r
+\r
+Some tests are currently broken for several reasons:\r
+1) in the context of e-mails, we implicitly mean past dates e.g. Monday\r
+ means the last Monday and not the next one, as it is currently\r
+ implemented by the parser.\r
+2) yesterday means "now -24 hours" and I think that should be\r
+ "midnight -24 hours".\r
+---\r
+ lib/getdate.c | 52 +++++++++++++++++++++++++++++++++++++++-----------\r
+ lib/getdate.y | 52 +++++++++++++++++++++++++++++++++++++++-----------\r
+ test/Makefile.local | 9 ++++++-\r
+ test/basic | 2 +-\r
+ test/date-parser | 37 ++++++++++++++++++++++++++++++++++++\r
+ test/notmuch-test | 2 +-\r
+ 6 files changed, 126 insertions(+), 28 deletions(-)\r
+ create mode 100755 test/date-parser\r
+\r
+diff --git a/lib/getdate.c b/lib/getdate.c\r
+index 57f33e9..685c51f 100644\r
+--- a/lib/getdate.c\r
++++ b/lib/getdate.c\r
+@@ -3471,19 +3471,50 @@ get_date (struct timespec *result, char const *p, struct timespec const *now)\r
+ #if TEST\r
+ \r
+ int\r
++_internal_error (const char *format, ...)\r
++{\r
++ va_list va_args;\r
++\r
++ va_start (va_args, format);\r
++\r
++ fprintf (stderr, "Internal error: ");\r
++ vfprintf (stderr, format, va_args);\r
++\r
++ exit (1);\r
++\r
++ return 1;\r
++}\r
++\r
++int\r
+ main (int ac, char **av)\r
+ {\r
+ char buff[BUFSIZ];\r
+ \r
+- printf ("Enter date, or blank line to exit.\n\t> ");\r
+- fflush (stdout);\r
+-\r
+- buff[BUFSIZ - 1] = '\0';\r
+- while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])\r
++ buff[BUFSIZ - 2] = '\0';\r
++ while (fgets (buff, BUFSIZ - 2, stdin) && buff[0])\r
+ {\r
+- struct timespec d;\r
++ struct timespec d, ref = { 0, 0 };\r
+ struct tm const *tm;\r
+- if (! get_date (&d, buff, NULL))\r
++ char *arrow;\r
++ arrow = strstr (buff, "->");\r
++ if (arrow)\r
++ *arrow = 0;\r
++ else {\r
++ arrow = buff + strlen (buff);\r
++ while (arrow > buff && *(arrow-1) == '\n')\r
++ arrow--;\r
++ *arrow-- = 0;\r
++ if (arrow >= buff && ( *arrow != ' ' || *arrow != '\t' ))\r
++ strcat (buff, " ");\r
++ }\r
++ if (ac > 1) {\r
++ struct tm tm_arg;\r
++ memset (&tm_arg, 0, sizeof (tm_arg));\r
++ strptime (av[1], "%Y-%m-%d %H:%M", &tm_arg);\r
++ ref.tv_sec = mktime (&tm_arg);\r
++ } else\r
++ clock_gettime (CLOCK_REALTIME, &ref);\r
++ if (! get_date (&d, buff, &ref))\r
+ printf ("Bad format - couldn't convert.\n");\r
+ else if (! (tm = localtime (&d.tv_sec)))\r
+ {\r
+@@ -3492,13 +3523,10 @@ main (int ac, char **av)\r
+ }\r
+ else\r
+ {\r
+- int ns = d.tv_nsec;\r
+- printf ("%04ld-%02d-%02d %02d:%02d:%02d.%09d\n",\r
++ printf ("%s-> %04ld-%02d-%02d %02d:%02d:%02d\n", buff,\r
+ tm->tm_year + 1900L, tm->tm_mon + 1, tm->tm_mday,\r
+- tm->tm_hour, tm->tm_min, tm->tm_sec, ns);\r
++ tm->tm_hour, tm->tm_min, tm->tm_sec);\r
+ }\r
+- printf ("\t> ");\r
+- fflush (stdout);\r
+ }\r
+ return 0;\r
+ }\r
+diff --git a/lib/getdate.y b/lib/getdate.y\r
+index d423f5b..657416e 100644\r
+--- a/lib/getdate.y\r
++++ b/lib/getdate.y\r
+@@ -1547,19 +1547,50 @@ get_date (struct timespec *result, char const *p, struct timespec const *now)\r
+ #if TEST\r
+ \r
+ int\r
++_internal_error (const char *format, ...)\r
++{\r
++ va_list va_args;\r
++\r
++ va_start (va_args, format);\r
++\r
++ fprintf (stderr, "Internal error: ");\r
++ vfprintf (stderr, format, va_args);\r
++\r
++ exit (1);\r
++\r
++ return 1;\r
++}\r
++\r
++int\r
+ main (int ac, char **av)\r
+ {\r
+ char buff[BUFSIZ];\r
+ \r
+- printf ("Enter date, or blank line to exit.\n\t> ");\r
+- fflush (stdout);\r
+-\r
+- buff[BUFSIZ - 1] = '\0';\r
+- while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])\r
++ buff[BUFSIZ - 2] = '\0';\r
++ while (fgets (buff, BUFSIZ - 2, stdin) && buff[0])\r
+ {\r
+- struct timespec d;\r
++ struct timespec d, ref = { 0, 0 };\r
+ struct tm const *tm;\r
+- if (! get_date (&d, buff, NULL))\r
++ char *arrow;\r
++ arrow = strstr (buff, "->");\r
++ if (arrow)\r
++ *arrow = 0;\r
++ else {\r
++ arrow = buff + strlen (buff);\r
++ while (arrow > buff && *(arrow-1) == '\n')\r
++ arrow--;\r
++ *arrow-- = 0;\r
++ if (arrow >= buff && ( *arrow != ' ' || *arrow != '\t' ))\r
++ strcat (buff, " ");\r
++ }\r
++ if (ac > 1) {\r
++ struct tm tm_arg;\r
++ memset (&tm_arg, 0, sizeof (tm_arg));\r
++ strptime (av[1], "%Y-%m-%d %H:%M", &tm_arg);\r
++ ref.tv_sec = mktime (&tm_arg);\r
++ } else\r
++ clock_gettime (CLOCK_REALTIME, &ref);\r
++ if (! get_date (&d, buff, &ref))\r
+ printf ("Bad format - couldn't convert.\n");\r
+ else if (! (tm = localtime (&d.tv_sec)))\r
+ {\r
+@@ -1568,13 +1599,10 @@ main (int ac, char **av)\r
+ }\r
+ else\r
+ {\r
+- int ns = d.tv_nsec;\r
+- printf ("%04ld-%02d-%02d %02d:%02d:%02d.%09d\n",\r
++ printf ("%s-> %04ld-%02d-%02d %02d:%02d:%02d\n", buff,\r
+ tm->tm_year + 1900L, tm->tm_mon + 1, tm->tm_mday,\r
+- tm->tm_hour, tm->tm_min, tm->tm_sec, ns);\r
++ tm->tm_hour, tm->tm_min, tm->tm_sec);\r
+ }\r
+- printf ("\t> ");\r
+- fflush (stdout);\r
+ }\r
+ return 0;\r
+ }\r
+diff --git a/test/Makefile.local b/test/Makefile.local\r
+index 302482b..72c5d74 100644\r
+--- a/test/Makefile.local\r
++++ b/test/Makefile.local\r
+@@ -8,10 +8,15 @@ $(dir)/smtp-dummy: $(dir)/smtp-dummy.c\r
+ $(dir)/qparser-test: $(dir)/qparser-test.o notmuch-config.o query-string.o lib/libnotmuch.a\r
+ $(call quiet,CXX $(CXXFLAGS)) $^ $(FINAL_LIBNOTMUCH_LDFLAGS) -o $@\r
+ \r
++getdate-src := getdate.c xutil.c c-ctype.c gettime.c\r
++$(dir)/getdate-test: $(getdate-src:%=lib/%)\r
++ $(call quiet,CC $(CFLAGS)) $(FINAL_CFLAGS) -lrt -DTEST $^ -o $@\r
++\r
++\r
+ .PHONY: test check\r
+-test: all $(dir)/smtp-dummy $(dir)/qparser-test\r
++test: all $(dir)/smtp-dummy $(dir)/qparser-test $(dir)/getdate-test\r
+ @${dir}/notmuch-test $(OPTIONS)\r
+ \r
+ check: test\r
+ \r
+-CLEAN := $(CLEAN) $(dir)/smtp-dummy $(dir)/qparser-test.o $(dir)/qparser-test\r
++CLEAN := $(CLEAN) $(dir)/smtp-dummy $(dir)/qparser-test.o $(dir)/qparser-test $(dir)/getdate-test\r
+diff --git a/test/basic b/test/basic\r
+index 3191bcc..bbf452f 100755\r
+--- a/test/basic\r
++++ b/test/basic\r
+@@ -52,7 +52,7 @@ test_expect_code 2 'failure to clean up causes the test to fail' '\r
+ # Ensure that all tests are being run\r
+ test_begin_subtest 'Ensure that all available tests will be run by notmuch-test'\r
+ tests_in_suite=$(grep TESTS= ../notmuch-test | sed -e "s/TESTS=\"\(.*\)\"/\1/" | tr " " "\n" | sort)\r
+-available=$(ls -1 ../ | grep -v -E "^(aggregate-results.sh|Makefile|Makefile.local|notmuch-test|README|test-lib.sh|test-results|tmp.*|valgrind|corpus*|emacs.expected-output|smtp-dummy|smtp-dummy.c|test-verbose|test.expected-output|qparser-test.*|qparser-test|qparser.expected-output)" | sort)\r
++available=$(ls -1 ../ | grep -v -E "^(aggregate-results.sh|Makefile|Makefile.local|notmuch-test|README|test-lib.sh|test-results|tmp.*|valgrind|corpus*|emacs.expected-output|smtp-dummy|smtp-dummy.c|test-verbose|test.expected-output|qparser-test.*|qparser-test|qparser.expected-output|getdate-test)" | sort)\r
+ test_expect_equal "$tests_in_suite" "$available"\r
+ \r
+ EXPECTED=../test.expected-output\r
+diff --git a/test/date-parser b/test/date-parser\r
+new file mode 100755\r
+index 0000000..1c13748\r
+--- /dev/null\r
++++ b/test/date-parser\r
+@@ -0,0 +1,37 @@\r
++#!/bin/bash\r
++test_description="date parser"\r
++. ./test-lib.sh\r
++\r
++# Note: 2011-1-11 is Tuesday\r
++\r
++test_begin_subtest "Date/time parsing"\r
++cat > input <<EOF\r
++now -> 2011-01-11 11:11:00\r
++2010-1-1 -> 2010-01-01 00:00:00\r
++Jan 2 -> 2011-01-02 00:00:00\r
++last Friday -> 2011-01-07 00:00:00\r
++2 hours ago -> 2011-01-11 09:11:00\r
++last month -> 2010-12-11 11:11:00\r
++month ago -> 2010-12-11 11:11:00\r
++8am -> 2011-01-11 08:00:00\r
++9:15 -> 2011-01-11 09:15:00\r
++12:34 -> 2011-01-11 12:34:00\r
++EOF\r
++output=$(../getdate-test "2011-1-11 11:11" < input)\r
++test_expect_equal "$output" "$(cat input)"\r
++\r
++\r
++test_begin_subtest "Broken - implicitely, we mean the past"\r
++cat > input <<EOF\r
++monday -> 2011-01-10 00:00:00\r
++yesterday -> 2011-01-10 00:00:00\r
++tomorrow -> 2011-01-12 00:00:00\r
++EOF\r
++output=$(../getdate-test "2011-1-11 11:11" < input)\r
++test_expect_equal "$output" "$(cat input)"\r
++\r
++# TODO: Some values should depend whether used with after/before (e.g.\r
++# query "before:yesterday or after:yesterday" should return everything\r
++# except mails from yesterday)\r
++\r
++test_done\r
+diff --git a/test/notmuch-test b/test/notmuch-test\r
+index 1e331b3..167e920 100755\r
+--- a/test/notmuch-test\r
++++ b/test/notmuch-test\r
+@@ -16,7 +16,7 @@ fi\r
+ \r
+ cd $(dirname "$0")\r
+ \r
+-TESTS="basic new qparser search search-output json thread-naming raw reply dump-restore uuencode thread-order author-order from-guessing long-id encoding emacs maildir-sync"\r
++TESTS="basic new qparser date-parser search search-output json thread-naming raw reply dump-restore uuencode thread-order author-order from-guessing long-id encoding emacs maildir-sync"\r
+ \r
+ # Clean up any results from a previous run\r
+ rm -r test-results >/dev/null 2>/dev/null\r
+-- \r
+1.7.2.3\r
+\r