/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Author :
* Damon Chaplin <damon@helixcode.com>
*
* Copyright 2000, Helix Code, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
/*
* This tests the recurrence rule expansion functions.
*/
#include <config.h>
#include <string.h>
#include <time.h>
#include <glib.h>
#include "cal-recur.h"
static void set_time (CalObjTime *cotime, gint year, gint month, gint day,
gint hour, gint minute, gint second);
static void display_occs (GArray *occs);
static GList* build_list (gint first, ...);
static gchar* time_to_string (CalObjTime *cotime);
static void do_test (gchar *description,
CalObjTime *event_start,
CalObjRecurrence *recur,
CalObjTime *interval_start,
CalObjTime *interval_end);
#define LIST_END 999
static void
test_yearly ()
{
CalObjTime event_start, interval_start, interval_end;
CalObjRecurrence recur;
set_time (&event_start, 2000, 0, 1, 0, 0, 0);
/* We set the interval to a wide range so we just test the event. */
set_time (&interval_start, 2000, 0, 1, 0, 0, 0);
set_time (&interval_end, 2010, 0, 1, 0, 0, 0);
memset (&recur, 0, sizeof (recur));
recur.type = CAL_RECUR_YEARLY;
recur.interval = 3;
recur.byweekno = build_list (3, 9, 24, LIST_END);
recur.byday = build_list (3, 0, 5, 0, LIST_END);
do_test ("YEARLY every 3 years in weeks 3, 9, 24 on Thu/Sat",
&event_start, &recur, &interval_start, &interval_end);
set_time (&interval_end, 2002, 0, 1, 0, 0, 0);
memset (&recur, 0, sizeof (recur));
recur.type = CAL_RECUR_YEARLY;
recur.interval = 1;
recur.bymonth = build_list (0, 6, LIST_END);
recur.byday = build_list (0, 0, 6, 0, LIST_END);
do_test ("YEARLY every year in Jan/Jul on Mon/Sun",
&event_start, &recur, &interval_start, &interval_end);
memset (&recur, 0, sizeof (recur));
recur.type = CAL_RECUR_YEARLY;
recur.interval = 1;
recur.bymonthday = build_list (3, 7, LIST_END);
do_test ("YEARLY every year on 3rd & 7th of the month",
&event_start, &recur, &interval_start, &interval_end);
memset (&recur, 0, sizeof (recur));
recur.type = CAL_RECUR_YEARLY;
recur.interval = 1;
recur.byyearday = build_list (15, 126, 360, LIST_END);
do_test ("YEARLY every year on 15th, 126th & 360th day of the year",
&event_start, &recur, &interval_start, &interval_end);
}
static void
test_monthly ()
{
CalObjTime event_start, interval_start, interval_end;
CalObjRecurrence recur;
set_time (&event_start, 2000, 0, 1, 0, 0, 0);
/* We set the interval to a wide range so we just test the event. */
set_time (&interval_start, 2000, 0, 1, 0, 0, 0);
set_time (&interval_end, 2002, 0, 1, 0, 0, 0);
memset (&recur, 0, sizeof (recur));
recur.type = CAL_RECUR_MONTHLY;
recur.interval = 1;
do_test ("MONTHLY every month",
&event_start, &recur, &interval_start, &interval_end);
}
static void
test_weekly ()
{
CalObjTime event_start, interval_start, interval_end;
CalObjRecurrence recur;
set_time (&event_start, 2000, 0, 1, 0, 0, 0);
/* We set the interval to a wide range so we just test the event. */
set_time (&interval_start, 2000, 0, 1, 0, 0, 0);
set_time (&interval_end, 2002, 0, 1, 0, 0, 0);
memset (&recur, 0, sizeof (recur));
recur.type = CAL_RECUR_WEEKLY;
recur.interval = 1;
do_test ("WEEKLY every week",
&event_start, &recur, &interval_start, &interval_end);
}
static void
test_daily ()
{
CalObjTime event_start, interval_start, interval_end;
CalObjRecurrence recur;
set_time (&event_start, 2000, 0, 1, 0, 0, 0);
/* We set the interval to a wide range so we just test the event. */
set_time (&interval_start, 2000, 0, 1, 0, 0, 0);
set_time (&interval_end, 2000, 6, 1, 0, 0, 0);
memset (&recur, 0, sizeof (recur));
recur.type = CAL_RECUR_DAILY;
recur.interval = 1;
do_test ("DAILY every day",
&event_start, &recur, &interval_start, &interval_end);
}
static void
test_hourly ()
{
CalObjTime event_start, interval_start, interval_end;
CalObjRecurrence recur;
set_time (&event_start, 2000, 0, 1, 2, 15, 0);
/* We set the interval to a wide range so we just test the event. */
set_time (&interval_start, 2000, 0, 1, 0, 0, 0);
set_time (&interval_end, 2002, 0, 1, 0, 0, 0);
memset (&recur, 0, sizeof (recur));
recur.type = CAL_RECUR_HOURLY;
recur.interval = 3;
recur.bymonth = build_list (3, 11, LIST_END);
recur.byday = build_list (2, 0, 4, 0, LIST_END);
do_test ("HOURLY every 3 hours in Apr/Dec on Wed & Fri",
&event_start, &recur, &interval_start, &interval_end);
}
static void
test_minutely ()
{
CalObjTime event_start, interval_start, interval_end;
CalObjRecurrence recur;
set_time (&event_start, 2000, 0, 1, 0, 0, 0);
/* We set the interval to a wide range so we just test the event. */
set_time (&interval_start, 2000, 0, 1, 0, 0, 0);
set_time (&interval_end, 2000, 0, 2, 0, 0, 0);
memset (&recur, 0, sizeof (recur));
recur.type = CAL_RECUR_MINUTELY;
recur.interval = 45;
do_test ("MINUTELY every 45 minutes",
&event_start, &recur, &interval_start, &interval_end);
}
static void
test_secondly ()
{
CalObjTime event_start, interval_start, interval_end;
CalObjRecurrence recur;
set_time (&event_start, 2000, 0, 1, 0, 0, 0);
/* We set the interval to a wide range so we just test the event. */
set_time (&interval_start, 2000, 0, 1, 0, 0, 0);
set_time (&interval_end, 2000, 0, 2, 0, 0, 0);
memset (&recur, 0, sizeof (recur));
recur.type = CAL_RECUR_SECONDLY;
recur.interval = 15;
recur.byhour = build_list (2, 4, 6, LIST_END);
recur.byminute = build_list (0, 30, LIST_END);
do_test ("SECONDLY every 15 seconds at 2:00,2:30,4:00,4:30,6:00,6:30",
&event_start, &recur, &interval_start, &interval_end);
}
int
main (int argc, char *argv[])
{
test_yearly ();
test_monthly ();
test_weekly ();
test_daily ();
test_hourly ();
test_minutely ();
test_secondly ();
return 0;
}
static void
set_time (CalObjTime *cotime, gint year, gint month, gint day,
gint hour, gint minute, gint second)
{
cotime->year = year;
cotime->month = month;
cotime->day = day;
cotime->hour = hour;
cotime->minute = minute;
cotime->second = second;
}
static GList*
build_list (gint first, ...)
{
va_list args;
GList *list;
gint num;
va_start (args, first);
list = g_list_prepend (NULL, GINT_TO_POINTER (first));
num = va_arg (args, gint);
while (num != LIST_END) {
list = g_list_prepend (list, GINT_TO_POINTER (num));
num = va_arg (args, gint);
}
list = g_list_reverse (list);
va_end (args);
return list;
}
static void
do_test (gchar *description,
CalObjTime *event_start,
CalObjRecurrence *recur,
CalObjTime *interval_start,
CalObjTime *interval_end)
{
GArray *occs;
g_print ("========================================================\n");
g_print ("%s\n", description);
g_print ("(From %s", time_to_string (interval_start));
g_print (" To %s)\n\n", time_to_string (interval_end));
occs = cal_obj_expand_recurrence (event_start, recur,
interval_start, interval_end);
display_occs (occs);
g_array_free (occs, TRUE);
}
static gchar*
time_to_string (CalObjTime *cotime)
{
static gchar buffer[64];
gint month;
gchar *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "XXX" };
month = cotime->month;
if (month < 0 || month > 12)
month = 12;
sprintf (buffer, "%s %2i %02i:%02i:%02i %4i",
months[month], cotime->day,
cotime->hour, cotime->minute, cotime->second,
cotime->year);
return buffer;
}
static void
display_occs (GArray *occs)
{
CalObjTime *occ;
gint len, i;
struct tm t;
len = occs->len;
for (i = 0; i < len; i++) {
occ = &g_array_index (occs, CalObjTime, i);
t.tm_sec = occ->second;
t.tm_min = occ->minute;
t.tm_hour = occ->hour;
t.tm_mday = occ->day;
t.tm_mon = occ->month;
t.tm_year = occ->year - 1900;
t.tm_isdst = -1;
mktime (&t);
g_print ("%s", asctime (&t));
}
}