1 /* Evolution calendar client - test program
3 * Copyright (C) 2000 Ximian, Inc.
4 * Copyright (C) 2000 Ximian, Inc.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of version 2 of the GNU Lesser General Public
8 * License as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27 #include <glib/gi18n.h>
28 #include <libecal/e-cal.h>
29 #include <libecal/e-cal-component.h>
30 #include <libecal/e-cal-time-util.h>
31 #include <libical/ical.h>
33 /* start_testing_scaffold */
34 #define mu_assert(message, test) do { if (!(test)) return message; else { tests_passed++; return NULL;}} while (0)
35 #define mu_run_test(test) do { char *message = test; tests_run++; \
36 if (message) { cl_printf (client, "***Error***\n%s\n", message); break;} } while (0)
38 static int tests_run = 0;
39 static int tests_passed = 0;
40 /* end_testing_scaffold */
45 static GMainLoop *loop;
47 /* Prints a message with a client identifier */
49 cl_printf (ECal *client, const char *format, ...)
53 va_start (args, format);
54 if ( client != client1)
56 printf ("Client %s: ", "Test");
57 vprintf (format, args);
62 objects_added_cb (GObject *object, GList *objects, gpointer data)
66 for (l = objects; l; l = l->next)
67 cl_printf (data, "Object added %s\n", icalcomponent_get_uid (l->data));
71 objects_modified_cb (GObject *object, GList *objects, gpointer data)
75 for (l = objects; l; l = l->next)
76 cl_printf (data, "Object modified %s\n", icalcomponent_get_uid (l->data));
80 objects_removed_cb (GObject *object, GList *objects, gpointer data)
84 for (l = objects; l; l = l->next)
85 cl_printf (data, "Object removed %s\n", icalcomponent_get_uid (l->data));
89 view_done_cb (GObject *object, ECalendarStatus status, gpointer data)
91 cl_printf (data, "View done\n");
95 list_uids (ECal *client)
97 GList *objects = NULL;
100 if (!e_cal_get_object_list (client, "(contains? \"any\" \"test\")", &objects, NULL))
103 cl_printf (client, "UIDS: ");
105 cl_printf (client, "\nGot %d objects\n", g_list_length (objects));
109 for (l = objects; l; l = l->next) {
112 uid = icalcomponent_get_uid (l->data);
113 printf ("`%s' ", uid);
118 for (l = objects; l; l = l->next) {
119 printf ("------------------------------\n");
120 printf ("%s", icalcomponent_as_ical_string (l->data));
121 printf ("------------------------------\n");
125 e_cal_free_object_list (objects);
130 /* Callback used when a client is destroyed */
132 client_destroy_cb (gpointer data, GObject *object)
134 if (E_CAL (object) == client1)
136 else if (E_CAL (object) == client2)
139 g_assert_not_reached ();
141 if (!client1 && !client2)
142 g_main_loop_quit (loop);
146 test_object_creation (ECal *client, char **uid)
148 ECalComponent *comp, *comp_retrieved;
149 icalcomponent *icalcomp, *icalcomp_retrieved;
150 struct icaltimetype tt;
151 ECalComponentText text;
152 ECalComponentDateTime dt;
153 ECalComponentTransparency transp;
155 GError *error = NULL;
157 comp = e_cal_component_new ();
159 e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_EVENT);
160 text.value = "Creation of new test event";
162 e_cal_component_set_summary (comp, &text);
163 tt = icaltime_from_string ("20040109T090000Z");
166 e_cal_component_set_dtstart (comp, &dt);
167 tt = icaltime_from_string ("20040109T103000");
170 e_cal_component_set_dtend (comp, &dt);
171 e_cal_component_set_transparency (comp, E_CAL_COMPONENT_TRANSP_OPAQUE);
174 e_cal_component_commit_sequence (comp);
175 icalcomp = e_cal_component_get_icalcomponent (comp);
176 if (!e_cal_create_object (client, icalcomp, uid, &error)) {
177 cl_printf (client, "Object creation: %s\n", error->message);
180 return "Test Object Creation failed";
182 e_cal_component_commit_sequence (comp);
183 if (!e_cal_get_object (client, *uid, NULL, &icalcomp_retrieved, &error)) {
184 cl_printf (client, "Object retrieval: %s\n", error->message);
188 return "Test Object Creation failed";
192 comp_retrieved = e_cal_component_new ();
193 if (!e_cal_component_set_icalcomponent (comp_retrieved, icalcomp_retrieved)) {
194 cl_printf (client, "Could not set icalcomponent\n");
198 g_free (icalcomp_retrieved);
199 return "Test Object Creation failed";
202 /* Dumping icalcomp into a string is not useful as the retrieved object
203 * has some generated information like timestamps. We compare
204 * member values we set during creation*/
205 compare = e_cal_component_event_dates_match (comp, comp_retrieved);
208 e_cal_component_get_transparency (comp_retrieved, &transp);
209 compare = (transp == E_CAL_COMPONENT_TRANSP_OPAQUE);
212 g_free (comp_retrieved);
215 g_free (icalcomp_retrieved);
217 mu_assert ("Test Object creation : Created object does not match retrieved data\n", compare);
222 test_object_modification (ECal *client, char *uid)
224 const char *summary = "This summary was modified";
225 icalcomponent *icalcomp, *icalcomp_modified;
227 GError *error = NULL;
229 if (!e_cal_get_object (client, uid, NULL, &icalcomp, &error)) {
230 cl_printf (client, "Test Modify object : Could not get the object: %s\n", error->message);
232 return error->message;
235 // modify one property of the icalcomp and save it. Now retrieve it and
237 icalcomponent_set_summary (icalcomp, summary);
238 if (!e_cal_modify_object (client, icalcomp, CALOBJ_MOD_THIS, &error)) {
239 cl_printf (client, "Test Modify object : Could not modify the object: %s\n", error->message);
242 return error->message;
245 if (!e_cal_get_object (client, uid, NULL, &icalcomp_modified, &error)) {
246 cl_printf (client, "Test Modify object : Could not get the modified object: %s\n", error->message);
249 return "Test Object Creation failed";
252 compare = !strcmp ( icalcomponent_get_summary (icalcomp_modified), summary);
256 g_free (icalcomp_modified);
258 mu_assert ("Test Modify object : Modification failed\n", compare);
264 test_object_removal (ECal *client)
269 icalcomponent *icalcomp;
270 gboolean compare = 1;
271 GError *error = NULL;
273 comp = e_cal_component_new ();
274 e_cal_component_commit_sequence (comp);
275 icalcomp = e_cal_component_get_icalcomponent (comp);
276 if (!e_cal_create_object (client, icalcomp, &uid, &error)) {
277 cl_printf (client, "Test object removal - Object creation: %s\n", error->message);
278 g_object_unref (comp);
279 g_object_unref(icalcomp);
280 return "Test Object Removal failed\n";
283 if (!e_cal_remove_object (client, uid, &error)) {
284 cl_printf (client, "Test object removal - Could not remove the object\n");
286 g_object_unref (comp);
287 g_object_unref (icalcomp);
288 return "Test Object Removal failed\n";
292 compare = e_cal_get_object (client, uid, NULL, &icalcomp, &error);
295 g_object_unref (comp);
296 g_object_unref (icalcomp);
298 mu_assert ("Test object removal - Failed\n", compare);
304 test_get_alarms_in_range (ECal *client)
308 time_t start = time (NULL), end;
311 utc = icaltimezone_get_utc_timezone ();
312 start = time_from_isodate ("20040212T000000Z");
313 end = time_add_day_with_zone (start, 2, utc);
315 alarms = e_cal_get_alarms_in_range (client, start, end);
316 compare = (g_slist_length (alarms) == 3);
318 e_cal_free_alarms (alarms);
319 mu_assert ("Test getting alarms in range\n", compare);
325 test_set_uri (ECal *client, const gchar *uri)
327 /* The uri is set as part of create_client call. This method merely
328 * verifies it was done correctly.
331 gboolean compare = 0;
332 cal_uri = g_strconcat ("file://", uri, NULL);
333 compare = !strcmp (e_cal_get_uri (client), cal_uri);
336 mu_assert ("Test set_uri : uri was not set correctly\n", compare);
342 test_cal_loaded (ECal *client)
344 /* Test one loaded calendar and another that is not loaded. */
345 mu_assert ("Test get_cal_load_state : Failed \n",
346 (E_CAL_LOAD_LOADED == e_cal_get_load_state (client)) &&
347 (E_CAL_LOAD_NOT_LOADED == e_cal_get_load_state (NULL)));
353 test_get_source (ECal *client, const gchar *expected)
358 gboolean compare = 0;
360 source = e_cal_get_source (client);
361 uri = e_source_get_uri (source);
362 cal_uri = g_strconcat ("file://", expected, NULL);
363 compare = !strcmp (expected, uri);
366 mu_assert ("Test get_source : Failed\n", compare);
372 test_query (ECal *client, const char *query, int expected)
374 /* This uses pre-loaded data. Hence its results are valid only
375 * when called before any write operation is performed.
378 GList *objects = NULL;
380 if (!e_cal_get_object_list (client, query, &objects, NULL))
381 return "Could not get the list of objects";
382 i = g_list_length (objects);
383 e_cal_free_object_list (objects);
385 mu_assert ("Test get_object_list : Expected number of objects not found", i == expected);
392 test_e_cal_new (ECal **cal, const char *uri)
394 GError *error = NULL;
395 char *cal_uri, *cal_file;
396 gboolean created = 0;
398 cal_uri = g_strconcat ("file://", uri, NULL);
399 *cal = e_cal_new_from_uri (cal_uri, E_CAL_SOURCE_TYPE_EVENT);
401 g_message (G_STRLOC ": could not create the client");
403 return "Test Creation of new calendar : Failed";
405 g_object_weak_ref (G_OBJECT (*cal), client_destroy_cb, NULL);
407 cl_printf (*cal, "Calendar loading `%s'...\n", uri);
409 if (!e_cal_open (*cal, FALSE, &error)) {
410 cl_printf (*cal, "Load/create %s\n", error->message);
412 return "Test creation of new calendar : Failed";
415 cal_file = g_strconcat (uri, "/calendar.ics", NULL);
417 created = g_file_test (cal_file, G_FILE_TEST_EXISTS);
421 mu_assert ("Test creation of new calendar : Failed", created);
427 test_e_cal_remove (ECal *ecal, const char *uri)
430 GError *error = NULL;
431 gboolean removed = 0;
433 cal_uri = g_strconcat (uri, "/calendar.ics", NULL);
434 if (!e_cal_remove (ecal, &error)) {
435 cl_printf (ecal, "Test Calendar removal : Could not remove the Calendar : %s\n", error->message);
438 removed = !g_file_test (uri, G_FILE_TEST_EXISTS);
441 mu_assert ("Test Remove calendar : Failed ", removed);
448 test_new_system_calendar(void)
454 cal = e_cal_new_system_calendar ();
455 uri = g_build_filename (g_get_home_dir (), ".evolution", "calendar", "local", "system", "calendar.ics", NULL);
456 created = g_file_test (uri, G_FILE_TEST_EXISTS);
459 mu_assert ("Test creation of default system calendar : Failed", created);
465 test_new_system_tasks(void)
471 cal = e_cal_new_system_tasks ();
472 uri = g_build_filename (g_get_home_dir (), ".evolution", "tasks", "local", "system", "tasks.ics", NULL);
473 created = g_file_test (uri, G_FILE_TEST_EXISTS);
476 mu_assert ("Test creation of default system tasks : Failed", created);
482 test_new_system_memos(void)
488 cal = e_cal_new_system_memos ();
489 uri = g_build_filename (g_get_home_dir (), ".evolution", "memos", "local", "system", "journal.ics", NULL);
490 created = g_file_test (uri, G_FILE_TEST_EXISTS);
493 mu_assert ("Test creation of default system memos : Failed", created);
499 test_get_free_busy (ECal *client)
501 // TODO uses NULL for users and currently specific to file backend.
502 GList *l, *freebusy = NULL;
503 GError *error = NULL;
505 time_t start = time (NULL), end;
507 utc = icaltimezone_get_utc_timezone ();
508 start = time_from_isodate ("20040212T000000Z");
509 end = time_add_day_with_zone (start, 2, utc);
511 if (!e_cal_get_free_busy (client, NULL, start, end, &freebusy, &error)) {
512 cl_printf (client, "Test free/busy : Could not retrieve free busy information : %s\n", error->message);
513 return error->message;
516 cl_printf (client, "Printing free busy information\n");
517 for (l = freebusy; l; l = l->next) {
519 ECalComponent *comp = E_CAL_COMPONENT (l->data);
521 comp_string = e_cal_component_get_as_string (comp);
522 cl_printf (client, "%s\n\n", comp_string);
523 g_object_unref (comp);
524 g_free (comp_string);
528 cl_printf (client, "free_busy was returned but NULL");
535 test_get_default_object (ECal *client)
537 icalcomponent *icalcomp;
538 GError *error = NULL;
540 if (e_cal_get_default_object (client, &icalcomp, &error)) {
541 ical_string = icalcomponent_as_ical_string (icalcomp);
542 cl_printf (client, "Obtained default object: %s\n", ical_string);
543 g_free (ical_string);
548 cl_printf (client, "Test Get default object : Could not get the default object: %s\n", error->message);
549 return error->message;
553 /* XXX The string pasted below is *really* ugly. Alternatively, it could be
554 * read from a file at run-time. Not sure if it is an elegant solution when
555 * multiple clients try to load the same file during stress testing.
556 * how can this be done better ?
560 UID:20040213T055519Z-15802-500-1-3@testcal\
561 DTSTAMP:20040213T055519Z\
562 DTSTART;TZID=/softwarestudio.org/Olson_20011030_5/Asia/Calcutta:\
564 DTEND;TZID=/softwarestudio.org/Olson_20011030_5/Asia/Calcutta:\
568 SUMMARY:Test - Travel plans to Kansas\
569 LOCATION:Yellow Brick road\
571 ORGANIZER;CN=dorothy:MAILTO:dorothy@oz\
572 DESCRIPTION: Discuss way to home\
573 ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;\
574 RSVP=TRUE;CN=dorothy;LANGUAGE=en:MAILTO:dorothy@oz\
575 ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;\
576 RSVP=TRUE;CN=tinman;LANGUAGE=en:MAILTO:tinman@oz\
577 ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;\
578 RSVP=TRUE;CN=toto;LANGUAGE=en:MAILTO:toto@oz\
579 ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=OPT-PARTICIPANT;PARTSTAT=NEEDS-ACTION;\
580 RSVP=TRUE;CN=scarecrow;LANGUAGE=en:MAILTO:scarecrow@oz\
581 LAST-MODIFIED:20040213T055647Z\
585 test_get_object (ECal *client)
587 const char *uid = "20040213T055519Z-15802-500-1-3@testcal";
589 icalcomponent *icalcomp;
591 GError *error = NULL;
593 if (!e_cal_get_object (client, uid, NULL, &icalcomp, &error)) {
594 cl_printf (client, "Test Get object : Could not get the object: %s\n", error->message);
595 return error->message;
598 actual = icalcomponent_as_ical_string (icalcomp);
599 compare = !strcmp (actual, EXPECTED);
603 mu_assert ("Test : get_object does not match the expected output", compare);
608 test_timezones (ECal *client)
611 GError *error = NULL;
612 if (!e_cal_get_timezone (client, "UTC", &zone, &error))
614 cl_printf (client, "Could not get the timezone\n");
617 printf ("\n\nTime Zones : \n%s *** %s", icaltimezone_get_display_name (zone), icaltimezone_get_tzid (zone));
618 printf ("\n\nTime Zones : \n%s", icaltimezone_get_location (zone));
625 all_tests(ECal *client, const gchar *uri)
629 mu_run_test (test_new_system_calendar ());
630 mu_run_test (test_new_system_tasks ());
631 mu_run_test (test_new_system_memos ());
632 mu_run_test (test_set_uri (client, uri));
633 mu_run_test (test_get_source (client, uri));
634 mu_run_test (test_cal_loaded (client));
636 /* test_query acts on pre-loaded data. Hence it must executed before
637 * any writes are made */
638 mu_run_test (test_query (client, "(contains? \"any\" \"test\")", 2));
639 mu_run_test (test_query (client, "(contains? \"summary\" \"Kansas\")", 1));
640 mu_run_test (test_query (client, "(contains? \"any\" \"gibberish\")", 0));
643 mu_run_test (test_get_default_object (client));
644 mu_run_test (test_get_object (client));
645 mu_run_test (test_get_free_busy (client));
646 mu_run_test (test_object_creation (client, &uid));
647 mu_run_test (test_object_modification (client, uid));
648 // mu_run_test (test_object_removal (client));
649 mu_run_test (test_get_alarms_in_range (client));
651 // tmp = g_strconcat (uri, "_tmp", NULL);
652 // mu_run_test (test_e_cal_new (&ecal, tmp));
653 // mu_run_test (test_e_cal_remove (ecal, tmp));
656 test_timezones (client);
661 /* Creates a calendar client and tries to load the specified URI into it */
663 create_client (ECal **client, const gchar *uri, ECalSourceType type, gboolean only_if_exists)
668 GError *error = NULL;
670 cal_uri = g_strconcat ("file://", uri, NULL);
671 *client = e_cal_new_from_uri (cal_uri, type);
673 g_message (G_STRLOC ": could not create the client");
677 g_object_weak_ref (G_OBJECT (*client), client_destroy_cb, NULL);
679 cl_printf (*client, "Calendar loading `%s'...\n", uri);
681 if (!e_cal_open (*client, only_if_exists, &error)) {
682 cl_printf (*client, "Load/create %s\n", error->message);
685 g_clear_error (&error);
687 if (!e_cal_get_query (*client, "(contains? \"any\" \"Event\")", &query, NULL)) {
688 cl_printf (*client, G_STRLOC ": Unable to obtain query");
692 g_signal_connect (G_OBJECT (query), "objects_added",
693 G_CALLBACK (objects_added_cb), client);
694 g_signal_connect (G_OBJECT (query), "objects_modified",
695 G_CALLBACK (objects_modified_cb), client);
696 g_signal_connect (G_OBJECT (query), "objects_removed",
697 G_CALLBACK (objects_removed_cb), client);
698 g_signal_connect (G_OBJECT (query), "view_done",
699 G_CALLBACK (view_done_cb), client);
701 e_cal_view_start (query);
703 results = all_tests (*client, uri);
704 cl_printf (*client, "\n\n\n*************Tests run: %d****************\n\n", tests_run);
705 cl_printf (*client, "*************Tests passed: %d*************\n\n\n", tests_passed);
707 cl_printf (*client, "***Failures********%s\n", results);
710 cl_printf (*client, "dump of the test calendar data");
717 main (int argc, char **argv)
720 bindtextdomain (GETTEXT_PACKAGE, EVOLUTION_LOCALEDIR);
721 textdomain (GETTEXT_PACKAGE);
724 loop = g_main_loop_new (NULL, TRUE);
726 /* arg1- file name; arg2- client suffix */
727 uri = g_strconcat (argv[1], argv[2], NULL);
728 create_client (&client1, uri, E_CAL_SOURCE_TYPE_EVENT, FALSE);
731 g_main_loop_run (loop);