summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTravis Reitter <treitter@gmail.com>2009-12-16 11:47:27 -0800
committerTravis Reitter <treitter@gmail.com>2009-12-16 14:39:46 -0800
commit584ca4ab3d3b69e25b4e2f2aa091a6106442064e (patch)
treec7506d968156c0a45a69e7ecae854ed30f2b59fd
parent7e4f85bcff4fa6f23ce7cef6c56de57b84e78c59 (diff)
downloadevolution-data-server-584ca4ab3d3b69e25b4e2f2aa091a6106442064e.tar.gz
Set up all the boilerplate for porting libecal from dbus-glib to gdbus and add a very basic regression test (as the beginning of an automated test suite, like libebook has.
-rw-r--r--calendar/libecal/Makefile.am30
-rw-r--r--calendar/libecal/e-cal.c88
-rw-r--r--calendar/libecal/e-data-cal-factory-gdbus-bindings.h51
-rw-r--r--calendar/libecal/e-data-cal-gdbus-bindings-common.h206
-rw-r--r--calendar/tests/ecal/Makefile.am44
-rw-r--r--calendar/tests/ecal/ecal-test-utils.c95
-rw-r--r--calendar/tests/ecal/ecal-test-utils.h39
-rw-r--r--calendar/tests/ecal/test-ecal-remove.c21
8 files changed, 545 insertions, 29 deletions
diff --git a/calendar/libecal/Makefile.am b/calendar/libecal/Makefile.am
index 45daa9480..c59359579 100644
--- a/calendar/libecal/Makefile.am
+++ b/calendar/libecal/Makefile.am
@@ -15,19 +15,21 @@ libecal_1_2_la_CPPFLAGS = \
$(LIBICAL_CFLAGS) \
$(EVOLUTION_CALENDAR_CFLAGS)
-libecal_1_2_la_SOURCES = \
- $(MARSHAL_GENERATED) \
- $(DBUS_GENERATED_H) \
- e-cal.c \
- e-cal-component.c \
- e-cal-recur.c \
- e-cal-time-util.c \
- e-cal-check-timezones.c \
- e-cal-system-timezone.c \
- e-cal-system-timezone.h \
- e-cal-util.c \
- e-cal-view.c \
- e-cal-view-private.h
+libecal_1_2_la_SOURCES = \
+ $(MARSHAL_GENERATED) \
+ $(DBUS_GENERATED_H) \
+ e-data-cal-factory-gdbus-bindings.h \
+ e-cal.c \
+ e-cal-component.c \
+ e-cal-recur.c \
+ e-cal-time-util.c \
+ e-cal-check-timezones.c \
+ e-cal-system-timezone.c \
+ e-cal-system-timezone.h \
+ e-cal-util.c \
+ e-cal-view.c \
+ e-cal-view-private.h \
+ $(NULL)
libecal_1_2_la_LIBADD = \
$(top_builddir)/libedataserver/libedataserver-1.2.la \
@@ -56,7 +58,7 @@ libecalinclude_HEADERS = \
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libecal-$(API_VERSION).pc
-DBUS_GENERATED_H = e-data-cal-factory-bindings.h e-data-cal-bindings.h e-data-cal-view-bindings.h
+DBUS_GENERATED_H = e-data-cal-bindings.h e-data-cal-view-bindings.h
%-bindings.h: $(top_srcdir)/calendar/libedata-cal/%.xml
dbus-binding-tool --mode=glib-client --output=$@ --prefix=$(subst -,_,$*) $^
diff --git a/calendar/libecal/e-cal.c b/calendar/libecal/e-cal.c
index 60950db71..e5cc2992c 100644
--- a/calendar/libecal/e-cal.c
+++ b/calendar/libecal/e-cal.c
@@ -44,12 +44,14 @@
#include "e-cal-time-util.h"
#include "e-cal-view-private.h"
#include "e-cal.h"
-#include "e-data-cal-factory-bindings.h"
+#include "e-data-cal-factory-gdbus-bindings.h"
#include "e-data-cal-bindings.h"
#include <libedata-cal/e-data-cal-types.h>
static DBusGConnection *connection = NULL;
static DBusGProxy *factory_proxy = NULL;
+static GDBusConnection *connection_gdbus = NULL;
+static GDBusProxy *factory_proxy_gdbus = NULL;
/* guards both connection and factory_proxy */
static GStaticRecMutex connection_lock = G_STATIC_REC_MUTEX_INIT;
@@ -88,6 +90,7 @@ struct _ECalPrivate {
gboolean read_only;
DBusGProxy *proxy;
+ GDBusProxy *gdbus_proxy;
/* The authentication function */
ECalAuthFunc auth_func;
@@ -378,6 +381,7 @@ e_cal_init (ECal *ecal)
priv->ldap_attribute = NULL;
priv->capabilities = NULL;
priv->proxy = NULL;
+ priv->gdbus_proxy = NULL;
priv->timezones = g_hash_table_new (g_str_hash, g_str_equal);
priv->default_zone = icaltimezone_get_utc_timezone ();
}
@@ -401,6 +405,7 @@ proxy_destroyed (gpointer data, GObject *object)
LOCK_CONN ();
factory_proxy = NULL;
priv->proxy = NULL;
+ priv->gdbus_proxy = NULL;
priv->load_state = E_CAL_LOAD_NOT_LOADED;
UNLOCK_CONN ();
@@ -420,7 +425,6 @@ e_cal_dispose (GObject *object)
if (priv->proxy) {
GError *error = NULL;
- g_object_weak_unref (G_OBJECT (priv->proxy), proxy_destroyed, ecal);
LOCK_CONN ();
org_gnome_evolution_dataserver_calendar_Cal_close (priv->proxy, &error);
g_object_unref (priv->proxy);
@@ -432,6 +436,18 @@ e_cal_dispose (GObject *object)
g_error_free (error);
}
}
+ if (priv->gdbus_proxy) {
+ g_object_weak_unref (G_OBJECT (priv->gdbus_proxy), proxy_destroyed, ecal);
+
+ LOCK_CONN ();
+ /* FIXME: uncomment this
+ e_data_cal_gdbus_close_sync (priv->gdbus_proxy, NULL);
+ */
+ g_object_unref (priv->gdbus_proxy);
+ priv->gdbus_proxy = NULL;
+ UNLOCK_CONN ();
+ }
+
(* G_OBJECT_CLASS (parent_class)->dispose) (object);
}
@@ -558,9 +574,10 @@ static gboolean
e_cal_activate(GError **error)
{
DBusError derror;
+ const gchar *factory_proxy_name;
LOCK_CONN ();
- if (G_LIKELY (factory_proxy)) {
+ if (G_LIKELY (factory_proxy && factory_proxy_gdbus)) {
UNLOCK_CONN ();
return TRUE;
}
@@ -596,6 +613,44 @@ e_cal_activate(GError **error)
}
}
+ factory_proxy_name = dbus_g_proxy_get_bus_name (factory_proxy);
+
+ /* FIXME: better to just watch for the proxy instead of using the
+ * connection directly? */
+ if (!connection_gdbus) {
+ connection_gdbus = g_dbus_connection_bus_get_private_sync (G_BUS_TYPE_SESSION, NULL, error);
+ if (!connection_gdbus) {
+ UNLOCK_CONN ();
+
+ g_warning (G_STRLOC ": failed to create the factory gdbus connection");
+
+ return FALSE;
+ }
+ }
+
+ /* FIXME: watch for changes to this proxy instead of relying upon
+ * dbus-glib to get the unique name */
+ if (!factory_proxy_gdbus) {
+ factory_proxy_gdbus = g_dbus_proxy_new_sync (connection_gdbus,
+ G_TYPE_DBUS_PROXY,
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
+ factory_proxy_name,
+ "/org/gnome/evolution/dataserver/calendar/CalFactory",
+ "org.gnome.evolution.dataserver.calendar.CalFactory",
+ NULL,
+ error);
+
+ if (!factory_proxy_gdbus) {
+ UNLOCK_CONN ();
+
+ g_warning (G_STRLOC ": failed to create the factory gdbus proxy, %s", (*error)->message);
+
+ return FALSE;
+ }
+
+ g_object_add_weak_pointer (G_OBJECT (factory_proxy_gdbus), (gpointer)&factory_proxy_gdbus);
+ }
+
UNLOCK_CONN ();
return TRUE;
@@ -805,7 +860,7 @@ e_cal_new (ESource *source, ECalSourceType type)
xml = e_source_to_standalone_xml (priv->source);
LOCK_CONN ();
- if (!org_gnome_evolution_dataserver_calendar_CalFactory_get_cal (factory_proxy, xml, convert_type (priv->type), &path, &error)) {
+ if (!e_data_cal_factory_gdbus_get_cal_sync (factory_proxy_gdbus, xml, convert_type (priv->type), &path, &error)) {
UNLOCK_CONN ();
g_free (xml);
g_warning ("Cannot get cal from factory: %s", error ? error->message : "Unknown error");
@@ -820,12 +875,33 @@ e_cal_new (ESource *source, ECalSourceType type)
"org.gnome.evolution.dataserver.calendar.Cal",
&error);
+ priv->gdbus_proxy = g_dbus_proxy_new_sync (connection_gdbus,
+ G_TYPE_DBUS_PROXY,
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
+ g_dbus_proxy_get_unique_bus_name (factory_proxy_gdbus),
+ path,
+ "org.gnome.evolution.dataserver.calendar.Cal",
+ NULL,
+ &error);
+
UNLOCK_CONN ();
- if (!priv->proxy)
+ if (!priv->proxy) {
+ g_warning (G_STRLOC ": cannot get dbus-glib proxy for calendar %s: %s", path, error->message);
+ g_free (path);
+ g_object_unref (ecal);
return NULL;
+ }
+
+ if (!priv->gdbus_proxy) {
+ g_warning (G_STRLOC ": cannot get gdbus proxy for calendar %s: %s", path, error->message);
+ g_free (path);
+ g_object_unref (ecal);
+ return NULL;
+ }
+ g_free (path);
- g_object_weak_ref (G_OBJECT (priv->proxy), proxy_destroyed, ecal);
+ g_object_weak_ref (G_OBJECT (priv->gdbus_proxy), proxy_destroyed, ecal);
dbus_g_proxy_add_signal (priv->proxy, "auth_required", G_TYPE_INVALID);
dbus_g_proxy_connect_signal (priv->proxy, "auth_required", G_CALLBACK (auth_required_cb), ecal, NULL);
diff --git a/calendar/libecal/e-data-cal-factory-gdbus-bindings.h b/calendar/libecal/e-data-cal-factory-gdbus-bindings.h
new file mode 100644
index 000000000..d4abe67d0
--- /dev/null
+++ b/calendar/libecal/e-data-cal-factory-gdbus-bindings.h
@@ -0,0 +1,51 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2009 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Author: Travis Reitter (travis.reitter@collabora.co.uk)
+ */
+
+#include <glib.h>
+#include <gdbus/gdbus.h>
+
+/* FIXME: move this file to a place where both sets of bindings can include it
+ */
+#include "e-data-cal-gdbus-bindings-common.h"
+
+G_BEGIN_DECLS
+
+/* FIXME: These bindings were created manually; replace with generated bindings
+ * when possible */
+
+static gboolean
+e_data_cal_factory_gdbus_get_cal_sync (GDBusProxy *proxy,
+ const char *IN_source,
+ const guint IN_type,
+ char **OUT_path,
+ GError **error)
+{
+ GVariant *parameters;
+ GVariant *retvals;
+
+ parameters = g_variant_new ("(su)", IN_source, IN_type);
+ retvals = g_dbus_proxy_invoke_method_sync (proxy, "getCal", parameters,
+ -1, NULL, error);
+
+ return demarshal_retvals__OBJPATH (retvals, OUT_path);
+}
+
+G_END_DECLS
diff --git a/calendar/libecal/e-data-cal-gdbus-bindings-common.h b/calendar/libecal/e-data-cal-gdbus-bindings-common.h
new file mode 100644
index 000000000..31e487ce0
--- /dev/null
+++ b/calendar/libecal/e-data-cal-gdbus-bindings-common.h
@@ -0,0 +1,206 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2009 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Author: Travis Reitter (travis.reitter@collabora.co.uk)
+ */
+
+#ifndef _E_DATA_CAL_GDBUS_BINDINGS_COMMON_H
+#define _E_DATA_CAL_GDBUS_BINDINGS_COMMON_H
+
+#include <glib.h>
+
+typedef struct {
+ GCallback cb;
+ gpointer user_data;
+} Closure;
+
+static void
+closure_free (Closure *closure)
+{
+ g_slice_free (Closure, closure);
+}
+
+static gboolean
+demarshal_retvals__VOID (GVariant *retvals)
+{
+ gboolean success = TRUE;
+
+ if (retvals)
+ g_variant_unref (retvals);
+ else
+ success = FALSE;
+
+ return success;
+}
+
+static gboolean
+demarshal_retvals__OBJPATH (GVariant *retvals, char **OUT_objpath1)
+{
+ gboolean success = TRUE;
+
+ if (retvals) {
+ const char *objpath1 = NULL;
+
+ g_variant_get (retvals, "(o)", &objpath1);
+ if (objpath1) {
+ *OUT_objpath1 = g_strdup (objpath1);
+ } else {
+ success = FALSE;
+ }
+
+ g_variant_unref (retvals);
+ } else {
+ success = FALSE;
+ }
+
+ return success;
+}
+
+static gboolean
+demarshal_retvals__STRING (GVariant *retvals, char **OUT_string1)
+{
+ gboolean success = TRUE;
+
+ if (retvals) {
+ const char *string1 = NULL;
+
+ g_variant_get (retvals, "(s)", &string1);
+ if (string1) {
+ *OUT_string1 = g_strdup (string1);
+ } else {
+ success = FALSE;
+ }
+
+ g_variant_unref (retvals);
+ } else {
+ success = FALSE;
+ }
+
+ return success;
+}
+
+static gboolean
+demarshal_retvals__STRINGVECTOR (GVariant *retvals, char ***OUT_strv1)
+{
+ gboolean success = TRUE;
+
+ if (retvals) {
+ GVariant *strv1_variant;
+ char **strv1 = NULL;
+ gint strv1_length;
+
+ /* retvals contains a (as) with length 1; de-shell the
+ * array of strings from the tuple */
+ strv1_variant = g_variant_get_child_value (retvals, 0);
+ strv1 = g_variant_dup_strv (strv1_variant, &strv1_length);
+
+ if (strv1) {
+ *OUT_strv1 = strv1;
+ } else {
+ success = FALSE;
+ }
+
+ g_variant_unref (retvals);
+ } else {
+ success = FALSE;
+ }
+
+ return success;
+}
+
+static gboolean
+demarshal_retvals__GPTRARRAY_with_GVALUEARRAY_with_UINT_STRING_endwith_endwith
+ (GVariant *retvals,
+ GPtrArray **OUT_ptrarray1)
+{
+ gboolean success = TRUE;
+
+ if (retvals) {
+ GVariant *array1_variant;
+ GVariantIter iter1;
+ GPtrArray *ptrarray1 = NULL;
+ const guint uint1_tmp;
+ const char *string1_tmp = NULL;
+
+ /* deshelling a (a(us)); there should always be exactly one
+ * a(us) in the outermost tuple */
+ array1_variant = g_variant_get_child_value (retvals, 0);
+ g_variant_iter_init (&iter1, array1_variant);
+
+ /* return NULL instead of an empty GPtrArray* if there's nothing
+ * to put in it */
+ if (g_variant_n_children (array1_variant) < 1) {
+ goto empty_inner_array;
+ }
+
+ ptrarray1 = g_ptr_array_new ();
+
+ while (g_variant_iter_next (&iter1, "(us)", &uint1_tmp, &string1_tmp)) {
+ GValueArray *valuearray = NULL;
+ GValue uint_value1 = {0};
+ GValue string_value1 = {0};
+
+ valuearray = g_value_array_new (2);
+ g_value_init (&uint_value1, G_TYPE_UINT);
+ g_value_init (&string_value1, G_TYPE_STRING);
+
+ g_value_set_uint (&uint_value1, uint1_tmp);
+ g_value_set_string (&string_value1, string1_tmp);
+
+ g_value_array_append (valuearray, &uint_value1);
+ g_value_array_append (valuearray, &string_value1);
+ g_ptr_array_add (ptrarray1, valuearray);
+ }
+
+empty_inner_array:
+ *OUT_ptrarray1 = ptrarray1;
+
+ g_variant_unref (retvals);
+ } else {
+ success = FALSE;
+ }
+
+ return success;
+}
+
+
+typedef void (*reply__VOID) (GDBusProxy *proxy,
+ GError *error,
+ gpointer user_data);
+
+typedef void (*reply__OBJPATH) (GDBusProxy *proxy,
+ char *OUT_path1,
+ GError *error,
+ gpointer user_data);
+
+typedef void (*reply__STRING) (GDBusProxy *proxy,
+ char *OUT_string1,
+ GError *error,
+ gpointer user_data);
+
+typedef void (*reply__STRINGVECTOR) (GDBusProxy *proxy,
+ char **OUT_strv1,
+ GError *error,
+ gpointer user_data);
+
+typedef void (*reply__GPTRARRAY_with_GVALUEARRAY_with_UINT_STRING_endwith_endwith) (GDBusProxy *proxy,
+ GPtrArray *OUT_ptrarray1,
+ GError *error,
+ gpointer user_data);
+
+#endif /* _E_DATA_CAL_GDBUS_BINDINGS_COMMON_H */
diff --git a/calendar/tests/ecal/Makefile.am b/calendar/tests/ecal/Makefile.am
index af5f5b851..0ba89f8f7 100644
--- a/calendar/tests/ecal/Makefile.am
+++ b/calendar/tests/ecal/Makefile.am
@@ -1,3 +1,27 @@
+noinst_LTLIBRARIES = libecal-test-utils.la
+libecal_test_utils_la_SOURCES = ecal-test-utils.c ecal-test-utils.h
+
+libecal_test_utils_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -DEVOLUTION_LOCALEDIR=\""$(localedir)"\" \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ -I$(top_srcdir)/calendar \
+ -I$(top_builddir)/calendar \
+ $(LIBICAL_CFLAGS) \
+ $(EVOLUTION_CALENDAR_CFLAGS) \
+ $(NULL)
+
+libecal_test_utils_la_LIBADD = \
+ $(top_builddir)/calendar/libecal/libecal-1.2.la \
+ $(EVOLUTION_CALENDAR_LIBS) \
+ $(NULL)
+
+TEST_ECAL_LIBS = \
+ $(libecal_test_utils_la_LIBADD) \
+ libecal-test-utils.la \
+ $(NULL)
+
EXTRA_DIST = \
$(test_scripts) \
testdata.ics
@@ -6,19 +30,21 @@ test_scripts = \
test-runner.sh \
cleanup.sh
+TESTS = \
+ test-ecal-remove \
+ $(NULL)
+
# The test program
-noinst_PROGRAMS = test-ecal test-recur test-search
+noinst_PROGRAMS = $(TESTS) test-ecal test-recur test-search
TEST_ECAL_CPPFLAGS= \
- $(AM_CPPFLAGS) \
- -DEVOLUTION_LOCALEDIR=\""$(localedir)"\" \
- -I$(top_srcdir) \
- -I$(top_builddir) \
- -I$(top_srcdir)/calendar \
- -I$(top_builddir)/calendar \
- $(LIBICAL_CFLAGS) \
- $(EVOLUTION_CALENDAR_CFLAGS)
+ $(libecal_test_utils_la_CPPFLAGS) \
+ $(NULL)
+
+test_ecal_remove_LDADD=$(TEST_ECAL_LIBS)
+test_ecal_remove_CPPFLAGS=$(TEST_ECAL_CPPFLAGS)
+# monolithic tests
test_ecal_SOURCES = test-ecal.c
test_ecal_CPPFLAGS = $(TEST_ECAL_CPPFLAGS)
test_ecal_INCLUDES = \
diff --git a/calendar/tests/ecal/ecal-test-utils.c b/calendar/tests/ecal/ecal-test-utils.c
new file mode 100644
index 000000000..a08193d87
--- /dev/null
+++ b/calendar/tests/ecal/ecal-test-utils.c
@@ -0,0 +1,95 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2009 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Author: Travis Reitter (travis.reitter@collabora.co.uk)
+ */
+
+#include <stdlib.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <libecal/e-cal.h>
+
+#include "ecal-test-utils.h"
+
+ECal*
+ecal_test_utils_cal_new_temp (char **uri,
+ ECalSourceType type)
+{
+ ECal *cal;
+ GError *error = NULL;
+ gchar *file_template;
+ char *uri_result;
+
+ file_template = g_build_filename (g_get_tmp_dir (),
+ "ecal-test-XXXXXX/", NULL);
+ g_mkstemp (file_template);
+
+ uri_result = g_filename_to_uri (file_template, NULL, &error);
+ if (!uri_result) {
+ g_warning ("failed to convert %s to an URI: %s", file_template,
+ error->message);
+ exit (1);
+ }
+ g_free (file_template);
+
+ /* create a temp calendar in /tmp */
+ g_print ("loading calendar\n");
+ cal = e_cal_new_from_uri (uri_result, type);
+ if (!cal) {
+ g_warning ("failed to create calendar: `%s'", *uri);
+ exit(1);
+ }
+
+ if (uri)
+ *uri = g_strdup (uri_result);
+
+ g_free (uri_result);
+
+ return cal;
+}
+
+void
+ecal_test_utils_cal_open (ECal *cal,
+ gboolean only_if_exists)
+{
+ GError *error = NULL;
+
+ if (!e_cal_open (cal, only_if_exists, &error)) {
+ const char *uri;
+
+ uri = e_cal_get_uri (cal);
+
+ g_warning ("failed to open calendar: `%s': %s", uri,
+ error->message);
+ exit(1);
+ }
+}
+
+void
+ecal_test_utils_cal_remove (ECal *cal)
+{
+ GError *error = NULL;
+
+ if (!e_cal_remove (cal, &error)) {
+ g_warning ("failed to remove calendar; %s\n", error->message);
+ exit(1);
+ }
+ g_print ("successfully removed the temporary calendar\n");
+
+ g_object_unref (cal);
+}
diff --git a/calendar/tests/ecal/ecal-test-utils.h b/calendar/tests/ecal/ecal-test-utils.h
new file mode 100644
index 000000000..38b3f0fd4
--- /dev/null
+++ b/calendar/tests/ecal/ecal-test-utils.h
@@ -0,0 +1,39 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2009 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 Lesser General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Author: Travis Reitter (travis.reitter@collabora.co.uk)
+ */
+
+#ifndef _ECAL_TEST_UTILS_H
+#define _ECAL_TEST_UTILS_H
+
+#include <glib.h>
+#include <libecal/e-cal.h>
+
+ECal*
+ecal_test_utils_cal_new_temp (char **uri,
+ ECalSourceType type);
+
+void
+ecal_test_utils_cal_open (ECal *cal,
+ gboolean only_if_exists);
+
+void
+ecal_test_utils_cal_remove (ECal *cal);
+
+#endif /* _ECAL_TEST_UTILS_H */
diff --git a/calendar/tests/ecal/test-ecal-remove.c b/calendar/tests/ecal/test-ecal-remove.c
new file mode 100644
index 000000000..7b48ff7bc
--- /dev/null
+++ b/calendar/tests/ecal/test-ecal-remove.c
@@ -0,0 +1,21 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+#include <stdlib.h>
+#include <libecal/e-cal.h>
+
+#include "ecal-test-utils.h"
+
+gint
+main (gint argc, gchar **argv)
+{
+ ECal *cal;
+ char *uri = NULL;
+
+ g_type_init ();
+
+ cal = ecal_test_utils_cal_new_temp (&uri, E_CAL_SOURCE_TYPE_EVENT);
+ ecal_test_utils_cal_open (cal, FALSE);
+ ecal_test_utils_cal_remove (cal);
+
+ return 0;
+}