- Date class now supports relative dates for construction (tomorrow, friday, eoy ...)

- Added unit tests for Date enhancements
- Added unit tests for duration recognition
- Task parsing now supports due: using relative dates
- Task parsing now supports recur: and until: attributes
- Task parsing now support private attributes base: and range:
This commit is contained in:
Paul Beckingham 2008-07-04 17:18:01 -04:00
parent 00b7a5f1b4
commit 06d595d944
11 changed files with 421 additions and 88 deletions

View file

@ -1,6 +1,7 @@
t.t
tdb.t
date.t
duration.t
pending.data
completed.data

View file

@ -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

View file

@ -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;
}

45
src/tests/duration.t.cpp Normal file
View file

@ -0,0 +1,45 @@
////////////////////////////////////////////////////////////////////////////////
// Copyright 2005 - 2008, Paul Beckingham. All rights reserved.
//
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <Date.h>
#include <test.h>
#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;
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -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;