diff --git a/ideas.txt b/ideas.txt index afeaad490..7c95de408 100644 --- a/ideas.txt +++ b/ideas.txt @@ -22,7 +22,7 @@ Test Suite Recurrence + new T::status recurring (stored as R) - - new user-specifiable attributes - recur: [until:] + + new user-specifiable attributes - recur: [until:] - duration: daily, day, 1d Nd diff --git a/src/Date.cpp b/src/Date.cpp index cd535e231..d386fb081 100644 --- a/src/Date.cpp +++ b/src/Date.cpp @@ -63,6 +63,10 @@ Date::Date (const std::string& mdy, const std::string& format /* = "m/d/Y" */) int day = 0; int year = 0; + // Before parsing according to "format", perhaps this is a relative date? + if (isRelativeDate (mdy)) + return; + unsigned int i = 0; // Index into mdy. for (unsigned int f = 0; f < format.length (); ++f) @@ -184,7 +188,7 @@ Date::Date (const std::string& mdy, const std::string& format /* = "m/d/Y" */) t.tm_mon = month - 1; t.tm_year = year - 1900; - mT = mktime (&t); + mT = mktime (&t); } //////////////////////////////////////////////////////////////////////////////// @@ -357,6 +361,22 @@ int Date::dayOfWeek () const return t->tm_wday; } +//////////////////////////////////////////////////////////////////////////////// +int Date::dayOfWeek (const std::string& input) +{ + std::string in = lowerCase (input); + + if (in == "sunday") return 0; + if (in == "monday") return 1; + if (in == "tuesday") return 2; + if (in == "wednesday") return 3; + if (in == "thursday") return 4; + if (in == "friday") return 5; + if (in == "saturday") return 6; + + return -1; +} + //////////////////////////////////////////////////////////////////////////////// int Date::month () const { @@ -414,6 +434,36 @@ bool Date::operator>= (const Date& rhs) return mT >= rhs.mT; } +//////////////////////////////////////////////////////////////////////////////// +bool Date::sameDay (const Date& rhs) +{ + if (this->year () == rhs.year () && + this->month () == rhs.month () && + this->day () == rhs.day ()) + return true; + + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +bool Date::sameMonth (const Date& rhs) +{ + if (this->year () == rhs.year () && + this->month () == rhs.month ()) + return true; + + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +bool Date::sameYear (const Date& rhs) +{ + if (this->year () == rhs.year ()) + return true; + + return false; +} + //////////////////////////////////////////////////////////////////////////////// Date Date::operator+ (const int delta) { @@ -441,3 +491,94 @@ time_t Date::operator- (const Date& rhs) } //////////////////////////////////////////////////////////////////////////////// +// If the input string looks like a relative date, determine that date, set mT +// and return true. +// +// What is a relative date? All of the following should be recognizable, and +// converted to an absolute date: +// wednesday +// fri +// 23rd +// today +// tomorrow +// yesterday +// eow (end of week) +// eom (end of month) +// eoy (end of year) +bool Date::isRelativeDate (const std::string& input) +{ + std::string in (lowerCase (input)); + + std::vector supported; + supported.push_back ("monday"); + supported.push_back ("tuesday"); + supported.push_back ("wednesday"); + supported.push_back ("thursday"); + supported.push_back ("friday"); + supported.push_back ("saturday"); + supported.push_back ("sunday"); + supported.push_back ("today"); + supported.push_back ("tomorrow"); + supported.push_back ("yesterday"); + supported.push_back ("eow"); + supported.push_back ("eom"); + supported.push_back ("eoy"); + + std::vector matches; + if (autoComplete (in, supported, matches) == 1) + { + std::string found = matches[0]; + Date today; + + // If day name. + int dow; + if ((dow = Date::dayOfWeek (found)) != -1 || + found == "eow") + { + if (found == "eow") + dow = 5; + + if (today.dayOfWeek () >= dow) + today += (dow - today.dayOfWeek () + 7) * 86400; + else + today += (dow - today.dayOfWeek ()) * 86400; + + mT = today.mT; + return true; + } + else if (found == "today") + { + mT = today.mT; + return true; + } + else if (found == "tomorrow") + { + mT = today.mT + 86400; + return true; + } + else if (found == "yesterday") + { + mT = today.mT - 86400; + return true; + } + else if (found == "eom") + { + Date then (today.month (), + daysInMonth (today.month (), today.year ()), + today.year ()); + mT = then.mT; + return true; + } + else if (found == "eoy") + { + Date then (12, 31, today.year ()); + mT = then.mT; + return true; + } +// \d|\d\d|\d\d\d|\d\d\d\d st|nd|rd|th + } + + return false; +} + +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/Date.h b/src/Date.h index 8f83f956a..ad3f659e0 100644 --- a/src/Date.h +++ b/src/Date.h @@ -52,11 +52,12 @@ public: static std::string monthName (int); static void dayName (int, std::string&); static std::string dayName (int); - int dayOfWeek () const; + static int dayOfWeek (const std::string&); int month () const; int day () const; int year () const; + int dayOfWeek () const; bool operator== (const Date&); bool operator!= (const Date&); @@ -64,6 +65,9 @@ public: bool operator> (const Date&); bool operator<= (const Date&); bool operator>= (const Date&); + bool sameDay (const Date&); + bool sameMonth (const Date&); + bool sameYear (const Date&); Date operator+ (const int); Date& operator+= (const int); @@ -71,6 +75,9 @@ public: time_t operator- (const Date&); +private: + bool isRelativeDate (const std::string&); + protected: time_t mT; }; diff --git a/src/parse.cpp b/src/parse.cpp index 36a972e3c..f69e8a8dc 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -241,9 +241,12 @@ static bool validAttribute ( return validPriority (value); } + // Some attributes are intended to be private. else if (name == "entry" || name == "start" || - name == "end") + name == "end" || + name == "base" || + name == "range") throw std::string ("\"") + name + "\" is not an attribute you may modify directly."; @@ -321,8 +324,7 @@ static bool validSubstitution ( //////////////////////////////////////////////////////////////////////////////// bool validDuration (const std::string& input) { - // TODO - return false; + return convertDuration (input) != 0 ? true : false; } //////////////////////////////////////////////////////////////////////////////// @@ -379,7 +381,10 @@ void parse ( std::string value = arg.substr (colon + 1, std::string::npos); if (validAttribute (name, value, conf)) - task.setAttribute (name, value); + { + if (name != "recur" || validDuration (value)) + task.setAttribute (name, value); + } } // Substitution of description text. diff --git a/src/task.h b/src/task.h index 549333330..c278e75ac 100644 --- a/src/task.h +++ b/src/task.h @@ -31,6 +31,7 @@ #include #include "Config.h" #include "Table.h" +#include "Date.h" #include "color.h" #include "TDB.h" #include "T.h" @@ -106,6 +107,8 @@ void formatTimeDeltaDays (std::string&, time_t); std::string formatSeconds (time_t); const std::string uuid (); const char* optionalBlankLine (Config&); +int convertDuration (const std::string&); +Date convertRelativeDate (const std::string&); // rules.cpp void initializeColorRules (Config&); diff --git a/src/tests/.gitignore b/src/tests/.gitignore index d77228426..1445bb223 100644 --- a/src/tests/.gitignore +++ b/src/tests/.gitignore @@ -1,6 +1,7 @@ t.t tdb.t date.t +duration.t pending.data completed.data diff --git a/src/tests/Makefile b/src/tests/Makefile index 7ea7453ca..c6c3ac3d8 100644 --- a/src/tests/Makefile +++ b/src/tests/Makefile @@ -1,4 +1,4 @@ -PROJECT = t.t tdb.t date.t +PROJECT = t.t tdb.t date.t duration.t CFLAGS = -I. -I.. -Wall -pedantic -ggdb3 -fno-rtti LFLAGS = -L/usr/local/lib OBJECTS = ../TDB.o ../T.o ../parse.o ../text.o ../Date.o ../util.o ../Config.o @@ -26,3 +26,6 @@ tdb.t: tdb.t.o $(OBJECTS) test.o date.t: date.t.o $(OBJECTS) test.o g++ date.t.o $(OBJECTS) test.o $(LFLAGS) -o date.t +duration.t: duration.t.o $(OBJECTS) test.o + g++ duration.t.o $(OBJECTS) test.o $(LFLAGS) -o duration.t + diff --git a/src/tests/date.t.cpp b/src/tests/date.t.cpp index e602c5b10..a28c2d6d5 100644 --- a/src/tests/date.t.cpp +++ b/src/tests/date.t.cpp @@ -9,104 +9,211 @@ //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - plan (63); + plan (97); - Date now; - Date yesterday; - yesterday -= 1; + try + { + Date now; + Date yesterday; + yesterday -= 1; - ok (yesterday <= now, "yesterday <= now"); - ok (yesterday < now, "yesterday < now"); - notok (yesterday == now, "!(yesterday == now)"); - ok (yesterday != now, "yesterday != now"); - ok (now >= yesterday, "now >= yesterday"); - ok (now > yesterday, "now > yesterday"); + ok (yesterday <= now, "yesterday <= now"); + ok (yesterday < now, "yesterday < now"); + notok (yesterday == now, "!(yesterday == now)"); + ok (yesterday != now, "yesterday != now"); + ok (now >= yesterday, "now >= yesterday"); + ok (now > yesterday, "now > yesterday"); - ok (Date::valid (2, 29, 2008), "valid: 2/29/2008"); - notok (Date::valid (2, 29, 2007), "invalid: 2/29/2007"); + // Loose comparisons. + Date left ("7/4/2008"); + Date comp1 ("7/4/2008"); + ok (left.sameDay (comp1), "7/4/2008 is on the same day as 7/4/2008"); + ok (left.sameMonth (comp1), "7/4/2008 is in the same month as 7/4/2008"); + ok (left.sameYear (comp1), "7/4/2008 is in the same year as 7/4/2008"); - ok (Date::leapYear (2008), "2008 is a leap year"); - notok (Date::leapYear (2007), "2007 is not a leap year"); - ok (Date::leapYear (2000), "2000 is a leap year"); - ok (Date::leapYear (1900), "1900 is a leap year"); + Date comp2 ("7/5/2008"); + notok (left.sameDay (comp2), "7/4/2008 is not on the same day as 7/5/2008"); + ok (left.sameMonth (comp2), "7/4/2008 is in the same month as 7/5/2008"); + ok (left.sameYear (comp2), "7/4/2008 is in the same year as 7/5/2008"); - is (Date::daysInMonth (2, 2008), 29, "29 days in February 2008"); - is (Date::daysInMonth (2, 2007), 28, "28 days in February 2007"); + Date comp3 ("8/4/2008"); + notok (left.sameDay (comp3), "7/4/2008 is not on the same day as 8/4/2008"); + notok (left.sameMonth (comp3), "7/4/2008 is not in the same month as 8/4/2008"); + ok (left.sameYear (comp3), "7/4/2008 is in the same year as 8/4/2008"); - is (Date::monthName (1), "January", "1 = January"); - is (Date::monthName (2), "February", "2 = February"); - is (Date::monthName (3), "March", "3 = March"); - is (Date::monthName (4), "April", "4 = April"); - is (Date::monthName (5), "May", "5 = May"); - is (Date::monthName (6), "June", "6 = June"); - is (Date::monthName (7), "July", "7 = July"); - is (Date::monthName (8), "August", "8 = August"); - is (Date::monthName (9), "September", "9 = September"); - is (Date::monthName (10), "October", "10 = October"); - is (Date::monthName (11), "November", "11 = November"); - is (Date::monthName (12), "December", "12 = December"); + Date comp4 ("7/4/2009"); + notok (left.sameDay (comp4), "7/4/2008 is not on the same day as 7/4/2009"); + notok (left.sameMonth (comp4), "7/4/2008 is not in the same month as 7/4/2009"); + notok (left.sameYear (comp4), "7/4/2008 is not in the same year as 7/4/2009"); - is (Date::dayName (0), "Sunday", "0 == Sunday"); - is (Date::dayName (1), "Monday", "1 == Monday"); - is (Date::dayName (2), "Tuesday", "2 == Tuesday"); - is (Date::dayName (3), "Wednesday", "3 == Wednesday"); - is (Date::dayName (4), "Thursday", "4 == Thursday"); - is (Date::dayName (5), "Friday", "5 == Friday"); - is (Date::dayName (6), "Saturday", "6 == Saturday"); + // Validity. + ok (Date::valid (2, 29, 2008), "valid: 2/29/2008"); + notok (Date::valid (2, 29, 2007), "invalid: 2/29/2007"); - Date happyNewYear (1, 1, 2008); - is (happyNewYear.dayOfWeek (), 2, "1/1/2008 == Tuesday"); - is (happyNewYear.month (), 1, "1/1/2008 == January"); - is (happyNewYear.day (), 1, "1/1/2008 == 1"); - is (happyNewYear.year (), 2008, "1/1/2008 == 2008"); + // Leap year. + ok (Date::leapYear (2008), "2008 is a leap year"); + notok (Date::leapYear (2007), "2007 is not a leap year"); + ok (Date::leapYear (2000), "2000 is a leap year"); + ok (Date::leapYear (1900), "1900 is a leap year"); - is (now - yesterday, 1, "today - yesterday == 1"); + // Days in month. + is (Date::daysInMonth (2, 2008), 29, "29 days in February 2008"); + is (Date::daysInMonth (2, 2007), 28, "28 days in February 2007"); - is (happyNewYear.toString (), "1/1/2008", "toString 1/1/2008"); + // Names. + is (Date::monthName (1), "January", "1 = January"); + is (Date::monthName (2), "February", "2 = February"); + is (Date::monthName (3), "March", "3 = March"); + is (Date::monthName (4), "April", "4 = April"); + is (Date::monthName (5), "May", "5 = May"); + is (Date::monthName (6), "June", "6 = June"); + is (Date::monthName (7), "July", "7 = July"); + is (Date::monthName (8), "August", "8 = August"); + is (Date::monthName (9), "September", "9 = September"); + is (Date::monthName (10), "October", "10 = October"); + is (Date::monthName (11), "November", "11 = November"); + is (Date::monthName (12), "December", "12 = December"); - int m, d, y; - happyNewYear.toMDY (m, d, y); - is (m, 1, "1/1/2008 == January"); - is (d, 1, "1/1/2008 == 1"); - is (y, 2008, "1/1/2008 == 2008"); + is (Date::dayName (0), "Sunday", "0 == Sunday"); + is (Date::dayName (1), "Monday", "1 == Monday"); + is (Date::dayName (2), "Tuesday", "2 == Tuesday"); + is (Date::dayName (3), "Wednesday", "3 == Wednesday"); + is (Date::dayName (4), "Thursday", "4 == Thursday"); + is (Date::dayName (5), "Friday", "5 == Friday"); + is (Date::dayName (6), "Saturday", "6 == Saturday"); - Date epoch (9, 8, 2001); - ok ((int)epoch.toEpoch () < 1000000000, "9/8/2001 < 1,000,000,000"); - epoch += 86400; - ok ((int)epoch.toEpoch () > 1000000000, "9/9/2001 > 1,000,000,000"); + is (Date::dayOfWeek ("SUNDAY"), 0, "SUNDAY == 0"); + is (Date::dayOfWeek ("sunday"), 0, "sunday == 0"); + is (Date::dayOfWeek ("Sunday"), 0, "Sunday == 0"); + is (Date::dayOfWeek ("Monday"), 1, "Monday == 1"); + is (Date::dayOfWeek ("Tuesday"), 2, "Tuesday == 2"); + is (Date::dayOfWeek ("Wednesday"), 3, "Wednesday == 3"); + is (Date::dayOfWeek ("Thursday"), 4, "Thursday == 4"); + is (Date::dayOfWeek ("Friday"), 5, "Friday == 5"); + is (Date::dayOfWeek ("Saturday"), 6, "Saturday == 6"); - Date fromEpoch (epoch.toEpoch ()); - is (fromEpoch.toString (), epoch.toString (), "ctor (time_t)"); + Date happyNewYear (1, 1, 2008); + is (happyNewYear.dayOfWeek (), 2, "1/1/2008 == Tuesday"); + is (happyNewYear.month (), 1, "1/1/2008 == January"); + is (happyNewYear.day (), 1, "1/1/2008 == 1"); + is (happyNewYear.year (), 2008, "1/1/2008 == 2008"); - Date fromString1 ("1/1/2008"); - is (fromString1.month (), 1, "ctor (std::string) -> m"); - is (fromString1.day (), 1, "ctor (std::string) -> d"); - is (fromString1.year (), 2008, "ctor (std::string) -> y"); + is (now - yesterday, 1, "today - yesterday == 1"); - Date fromString2 ("1/1/2008", "m/d/Y"); - is (fromString2.month (), 1, "ctor (std::string) -> m"); - is (fromString2.day (), 1, "ctor (std::string) -> d"); - is (fromString2.year (), 2008, "ctor (std::string) -> y"); + is (happyNewYear.toString (), "1/1/2008", "toString 1/1/2008"); - Date fromString3 ("20080101", "YMD"); - is (fromString3.month (), 1, "ctor (std::string) -> m"); - is (fromString3.day (), 1, "ctor (std::string) -> d"); - is (fromString3.year (), 2008, "ctor (std::string) -> y"); + int m, d, y; + happyNewYear.toMDY (m, d, y); + is (m, 1, "1/1/2008 == January"); + is (d, 1, "1/1/2008 == 1"); + is (y, 2008, "1/1/2008 == 2008"); - Date fromString4 ("12/31/2007"); - is (fromString4.month (), 12, "ctor (std::string) -> m"); - is (fromString4.day (), 31, "ctor (std::string) -> d"); - is (fromString4.year (), 2007, "ctor (std::string) -> y"); + Date epoch (9, 8, 2001); + ok ((int)epoch.toEpoch () < 1000000000, "9/8/2001 < 1,000,000,000"); + epoch += 86400; + ok ((int)epoch.toEpoch () > 1000000000, "9/9/2001 > 1,000,000,000"); - Date fromString5 ("12/31/2007", "m/d/Y"); - is (fromString5.month (), 12, "ctor (std::string) -> m"); - is (fromString5.day (), 31, "ctor (std::string) -> d"); - is (fromString5.year (), 2007, "ctor (std::string) -> y"); + Date fromEpoch (epoch.toEpoch ()); + is (fromEpoch.toString (), epoch.toString (), "ctor (time_t)"); + + // Date parsing. + Date fromString1 ("1/1/2008"); + is (fromString1.month (), 1, "ctor (std::string) -> m"); + is (fromString1.day (), 1, "ctor (std::string) -> d"); + is (fromString1.year (), 2008, "ctor (std::string) -> y"); + + Date fromString2 ("1/1/2008", "m/d/Y"); + is (fromString2.month (), 1, "ctor (std::string) -> m"); + is (fromString2.day (), 1, "ctor (std::string) -> d"); + is (fromString2.year (), 2008, "ctor (std::string) -> y"); + + Date fromString3 ("20080101", "YMD"); + is (fromString3.month (), 1, "ctor (std::string) -> m"); + is (fromString3.day (), 1, "ctor (std::string) -> d"); + is (fromString3.year (), 2008, "ctor (std::string) -> y"); + + Date fromString4 ("12/31/2007"); + is (fromString4.month (), 12, "ctor (std::string) -> m"); + is (fromString4.day (), 31, "ctor (std::string) -> d"); + is (fromString4.year (), 2007, "ctor (std::string) -> y"); + + Date fromString5 ("12/31/2007", "m/d/Y"); + is (fromString5.month (), 12, "ctor (std::string) -> m"); + is (fromString5.day (), 31, "ctor (std::string) -> d"); + is (fromString5.year (), 2007, "ctor (std::string) -> y"); + + Date fromString6 ("20071231", "YMD"); + is (fromString6.month (), 12, "ctor (std::string) -> m"); + is (fromString6.day (), 31, "ctor (std::string) -> d"); + is (fromString6.year (), 2007, "ctor (std::string) -> y"); + + // Relative dates. + Date r1 ("today"); + ok (r1.sameDay (now), "today = now"); + + Date r2 ("tomorrow"); + ok (r2.sameDay (now + 86400), "tomorrow = now + 1d"); + + Date r3 ("yesterday"); + ok (r3.sameDay (now - 86400), "yesterday = now - 1d"); + + Date r4 ("sunday"); + if (now.dayOfWeek () <= 0) + ok (r4.sameDay (now + (7 - now.dayOfWeek ()) * 86499), "next sunday"); + else + ok (r4.sameDay (now + (r4.dayOfWeek () - now.dayOfWeek ()) * 86400), "next sunday"); + + Date r5 ("monday"); + if (now.dayOfWeek () <= 1) + ok (r5.sameDay (now + (7 - now.dayOfWeek ()) * 86499), "next monday"); + else + ok (r5.sameDay (now + (r5.dayOfWeek () - now.dayOfWeek ()) * 86400), "next monday"); + + Date r6 ("tuesday"); + if (now.dayOfWeek () <= 2) + ok (r6.sameDay (now + (7 - now.dayOfWeek ()) * 86499), "next tuesday"); + else + ok (r6.sameDay (now + (r6.dayOfWeek () - now.dayOfWeek ()) * 86400), "next tuesday"); + + Date r7 ("wednesday"); + if (now.dayOfWeek () <= 3) + ok (r7.sameDay (now + (7 - now.dayOfWeek ()) * 86499), "next wednesday"); + else + ok (r7.sameDay (now + (r7.dayOfWeek () - now.dayOfWeek ()) * 86400), "next wednesday"); + + Date r8 ("thursday"); + if (now.dayOfWeek () <= 4) + ok (r8.sameDay (now + (7 - now.dayOfWeek ()) * 86499), "next thursday"); + else + ok (r8.sameDay (now + (r8.dayOfWeek () - now.dayOfWeek ()) * 86400), "next thursday"); + + Date r9 ("friday"); + if (now.dayOfWeek () <= 5) + ok (r9.sameDay (now + (7 - now.dayOfWeek ()) * 86499), "next friday"); + else + ok (r9.sameDay (now + (r9.dayOfWeek () - now.dayOfWeek ()) * 86400), "next friday"); + + Date r10 ("saturday"); + if (now.dayOfWeek () <= 6) + ok (r10.sameDay (now + (7 - now.dayOfWeek ()) * 86499), "next saturday"); + else + ok (r10.sameDay (now + (r10.dayOfWeek () - now.dayOfWeek ()) * 86400), "next saturday"); + + Date r11 ("eow"); + ok (r11 < now + (8 * 86400), "eow < 7 days away"); + + Date r12 ("eom"); + ok (r12.sameMonth (now), "eom in same month as now"); + + Date r13 ("eoy"); + ok (r13.sameYear (now), "eoy in same year as now"); + } + + catch (std::string& e) + { + std::cout << e << std::endl; + } - Date fromString6 ("20071231", "YMD"); - is (fromString6.month (), 12, "ctor (std::string) -> m"); - is (fromString6.day (), 31, "ctor (std::string) -> d"); - is (fromString6.year (), 2007, "ctor (std::string) -> y"); return 0; } diff --git a/src/tests/duration.t.cpp b/src/tests/duration.t.cpp new file mode 100644 index 000000000..df959e47a --- /dev/null +++ b/src/tests/duration.t.cpp @@ -0,0 +1,45 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright 2005 - 2008, Paul Beckingham. All rights reserved. +// +//////////////////////////////////////////////////////////////////////////////// +#include +#include +#include +#include <../task.h> + +//////////////////////////////////////////////////////////////////////////////// +// daily, day, d, Nd +// weekly, w, Nw, sennight, biweekly, fortnight +// monthly, m, bimonthly, Nm, semimonthly +// 1st 2nd 3rd 4th .. 31st +// quarterly, q, Nq +// biannual, biyearly, annual, semiannual, yearly, y, Na, Ny +int main (int argc, char** argv) +{ + plan (19); + + is (convertDuration ("daily"), 1, "duration daily = 1"); + is (convertDuration ("day"), 1, "duration day = 1"); + is (convertDuration ("d"), 0, "duration d = 1"); + is (convertDuration ("0d"), 0, "duration 0d = 0"); + is (convertDuration ("1d"), 1, "duration 1d = 1"); + is (convertDuration ("7d"), 7, "duration 7d = 7"); + is (convertDuration ("10d"), 10, "duration 10d = 10"); + is (convertDuration ("100d"), 100, "duration 100d = 100"); + + is (convertDuration ("weekly"), 7, "duration weekly = 7"); + is (convertDuration ("sennight"), 7, "duration sennight = 7"); + is (convertDuration ("biweekly"), 14, "duration biweekly = 14"); + is (convertDuration ("fortnight"), 14, "duration fortnight = 14"); + is (convertDuration ("week"), 7, "duration week = 7"); + is (convertDuration ("w"), 7, "duration w = 7"); + is (convertDuration ("0w"), 0, "duration 0w = 0"); + is (convertDuration ("1w"), 7, "duration 1w = 7"); + is (convertDuration ("7w"), 49, "duration 7w = 49"); + is (convertDuration ("10w"), 70, "duration 10w = 70"); + is (convertDuration ("100w"), 700, "duration 100w = 700"); + + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/tests/t.t.cpp b/src/tests/t.t.cpp index 86a847f58..f8d38e23b 100644 --- a/src/tests/t.t.cpp +++ b/src/tests/t.t.cpp @@ -31,7 +31,7 @@ //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - plan (4); + plan (5); T t; std::string s = t.compose (); @@ -48,6 +48,11 @@ int main (int argc, char** argv) is (s[37], 'X', "T::setStatus (deleted)"); diag (s); + t.setStatus (T::recurring); + s = t.compose (); + is (s[37], 'r', "T::setStatus (recurring)"); + diag (s); + // Round trip test. std::string sample = "00000000-0000-0000-0000-000000000000 - [] [] Sample"; T t2; diff --git a/src/util.cpp b/src/util.cpp index a908d3aa2..0449599cf 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -32,6 +32,7 @@ #include #include #include +#include "Date.h" #include "Table.h" #include "task.h" #include "../auto.h" @@ -236,3 +237,18 @@ const std::string uuid () #endif //////////////////////////////////////////////////////////////////////////////// +// Recognize the following constructs, and return the number of days represented +int convertDuration (const std::string& input) +{ + // TODO + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// +Date convertRelativeDate (const std::string& input) +{ + // TODO + return Date (); +} + +////////////////////////////////////////////////////////////////////////////////