[Telepathy-commits] [telepathy-glib/master] tests: remove test- prefix from all sources

Simon McVittie simon.mcvittie at collabora.co.uk
Tue Mar 17 07:44:10 PDT 2009


As well as making tab completion work better, this means .gitignore can
be much simpler.
---
 .gitignore                             |   37 +---
 tests/Makefile.am                      |   10 +-
 tests/availability-cmp.c               |   16 +
 tests/dbus/Makefile.am                 |    8 +
 tests/dbus/call-cancellation.c         |  472 ++++++++++++++++++++++++++++++++
 tests/dbus/dbus.c                      |  247 +++++++++++++++++
 tests/dbus/disconnection.c             |  376 +++++++++++++++++++++++++
 tests/dbus/example-no-protocols.c      |   96 +++++++
 tests/dbus/test-call-cancellation.c    |  472 --------------------------------
 tests/dbus/test-dbus.c                 |  247 -----------------
 tests/dbus/test-disconnection.c        |  376 -------------------------
 tests/dbus/test-example-no-protocols.c |   96 -------
 tests/heap.c                           |   39 +++
 tests/internal-debug.c                 |   79 ++++++
 tests/intset.c                         |  138 ++++++++++
 tests/test-availability-cmp.c          |   16 -
 tests/test-heap.c                      |   39 ---
 tests/test-internal-debug.c            |   79 ------
 tests/test-intset.c                    |  138 ----------
 tests/test-util.c                      |   58 ----
 tests/util.c                           |   58 ++++
 21 files changed, 1536 insertions(+), 1561 deletions(-)
 create mode 100644 tests/availability-cmp.c
 create mode 100644 tests/dbus/call-cancellation.c
 create mode 100644 tests/dbus/dbus.c
 create mode 100644 tests/dbus/disconnection.c
 create mode 100644 tests/dbus/example-no-protocols.c
 delete mode 100644 tests/dbus/test-call-cancellation.c
 delete mode 100644 tests/dbus/test-dbus.c
 delete mode 100644 tests/dbus/test-disconnection.c
 delete mode 100644 tests/dbus/test-example-no-protocols.c
 create mode 100644 tests/heap.c
 create mode 100644 tests/internal-debug.c
 create mode 100644 tests/intset.c
 delete mode 100644 tests/test-availability-cmp.c
 delete mode 100644 tests/test-heap.c
 delete mode 100644 tests/test-internal-debug.c
 delete mode 100644 tests/test-intset.c
 delete mode 100644 tests/test-util.c
 create mode 100644 tests/util.c

diff --git a/.gitignore b/.gitignore
index b874bc8..f060752 100644
--- a/.gitignore
+++ b/.gitignore
@@ -64,41 +64,8 @@ m4/lt~obsolete.m4
 missing
 stamp-h1
 tags
-tests/dbus/test-call-cancellation
-tests/dbus/test-channel-introspect
-tests/dbus/test-cli-group
-tests/dbus/test-cm
-tests/dbus/test-connection
-tests/dbus/test-connection-bug-18845
-tests/dbus/test-connection-getinterfaces-failure
-tests/dbus/test-connection-error
-tests/dbus/test-connection-handles
-tests/dbus/test-connection-inject-bug16307
-tests/dbus/test-contacts
-tests/dbus/test-contacts-bug-19101
-tests/dbus/test-contacts-mixin
-tests/dbus/test-dbus
-tests/dbus/test-disconnection
-tests/dbus/test-error-enum
-tests/dbus/test-example-no-protocols
-tests/dbus/test-finalized-in-invalidated-handler
-tests/dbus/test-group-mixin
-tests/dbus/test-handle-set
-tests/dbus/test-invalidated-while-invoking-signals
-tests/dbus/test-message-mixin
-tests/dbus/test-properties
-tests/dbus/test-message-mixin
-tests/dbus/test-self-handle
-tests/dbus/test-self-presence
-tests/dbus/test-text-mixin
-tests/dbus/test-text-respawn
-tests/dbus/test-unsupported-interface
-tests/test-asv
-tests/test-availability-cmp
-tests/test-heap
-tests/test-internal-debug
-tests/test-intset
-tests/test-util
+tests/dbus/test-*
+tests/test-*
 tests/tools/actual.h
 tests/tools/actual-body.h
 tools/telepathy-glib-env
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 705dc93..96bfe18 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -38,21 +38,21 @@ test_asv_SOURCES = \
     asv.c
 
 test_heap_SOURCES = \
-    test-heap.c
+    heap.c
 
 test_util_SOURCES = \
-    test-util.c
+    util.c
 
 test_intset_SOURCES = \
-    test-intset.c
+    intset.c
 
 test_availability_cmp_SOURCES = \
-    test-availability-cmp.c
+    availability-cmp.c
 
 # this needs to link against the static convenience library so that
 # _tp_debug is still visible
 test_internal_debug_SOURCES = \
-    test-internal-debug.c
+    internal-debug.c
 test_internal_debug_LDADD = \
     $(top_builddir)/telepathy-glib/libtelepathy-glib-internal.la
 
diff --git a/tests/availability-cmp.c b/tests/availability-cmp.c
new file mode 100644
index 0000000..56ce828
--- /dev/null
+++ b/tests/availability-cmp.c
@@ -0,0 +1,16 @@
+#include <glib.h>
+#include <telepathy-glib/connection.h>
+
+int main (int argc, char **argv)
+{
+  g_assert (tp_connection_presence_type_cmp_availability (
+    TP_CONNECTION_PRESENCE_TYPE_AWAY, TP_CONNECTION_PRESENCE_TYPE_UNSET) == 1);
+
+  g_assert (tp_connection_presence_type_cmp_availability (
+    TP_CONNECTION_PRESENCE_TYPE_BUSY, TP_CONNECTION_PRESENCE_TYPE_AVAILABLE) == -1);
+
+  g_assert (tp_connection_presence_type_cmp_availability (
+    TP_CONNECTION_PRESENCE_TYPE_UNKNOWN, 100) == 0);
+
+  return 0;
+}
diff --git a/tests/dbus/Makefile.am b/tests/dbus/Makefile.am
index 3094e5f..0fd0e0a 100644
--- a/tests/dbus/Makefile.am
+++ b/tests/dbus/Makefile.am
@@ -34,6 +34,8 @@ LDADD = \
     $(top_builddir)/telepathy-glib/libtelepathy-glib.la \
     $(top_builddir)/tests/lib/libtp-glib-tests.la
 
+test_call_cancellation_SOURCES = call-cancellation.c
+
 test_channel_introspect_SOURCES = channel-introspect.c
 
 test_cli_group_SOURCES = cli-group.c
@@ -62,9 +64,15 @@ test_contacts_bug_19101_SOURCES = contacts-bug-19101.c
 
 test_contacts_mixin_SOURCES = contacts-mixin.c
 
+test_dbus_SOURCES = dbus.c
+
+test_disconnection_SOURCES = disconnection.c
+
 test_error_enum_SOURCES = error-enum.c
 nodist_test_error_enum_SOURCES = _gen/errors-check.h
 
+test_example_no_protocols_SOURCES = example-no-protocols.c
+
 test_finalized_in_invalidated_handler_SOURCES = \
     finalized-in-invalidated-handler.c
 
diff --git a/tests/dbus/call-cancellation.c b/tests/dbus/call-cancellation.c
new file mode 100644
index 0000000..5f66b45
--- /dev/null
+++ b/tests/dbus/call-cancellation.c
@@ -0,0 +1,472 @@
+#include <telepathy-glib/dbus.h>
+#include <telepathy-glib/debug.h>
+#include <telepathy-glib/errors.h>
+#include <telepathy-glib/interfaces.h>
+#include <telepathy-glib/intset.h>
+#include <telepathy-glib/proxy-subclass.h>    /* for _invalidated etc. */
+#include <telepathy-glib/util.h>
+
+#include "tests/lib/myassert.h"
+#include "tests/lib/stub-object.h"
+
+/* just for convenience, since it's used a lot */
+#define PTR(ui) GUINT_TO_POINTER(ui)
+
+/* state tracking */
+static GMainLoop *mainloop;
+static TpDBusDaemon *a;
+static TpDBusDaemon *b;
+static TpDBusDaemon *c;
+static TpDBusDaemon *d;
+static TpDBusDaemon *e;
+static TpDBusDaemon *f;
+static TpDBusDaemon *g;
+static TpDBusDaemon *h;
+static TpDBusDaemon *i;
+static TpDBusDaemon *j;
+static TpDBusDaemon *k;
+static TpDBusDaemon *z;
+static TpIntSet *method_ok;
+static TpIntSet *method_error;
+static TpIntSet *freed_user_data;
+static gpointer copy_of_d;
+static gpointer copy_of_g;
+static gpointer copy_of_h;
+static gpointer copy_of_i;
+
+enum {
+    TEST_A,
+    TEST_B,
+    TEST_C,
+    TEST_D,
+    TEST_E,
+    TEST_F,
+    TEST_G,
+    TEST_H,
+    TEST_I,
+    TEST_J,
+    TEST_K,
+    TEST_Z = 25,
+    N_DAEMONS
+};
+
+static void
+destroy_user_data (gpointer user_data)
+{
+  guint which = GPOINTER_TO_UINT (user_data);
+  g_message ("User data %c destroyed", 'A' + which);
+  tp_intset_add (freed_user_data, which);
+}
+
+static void
+j_stub_destroyed (gpointer data,
+                  GObject *stub)
+{
+  destroy_user_data (data);
+}
+
+static void
+k_stub_destroyed (gpointer data,
+                  GObject *stub)
+{
+  TpProxyPendingCall **p = data;
+
+  tp_proxy_pending_call_cancel (*p);
+}
+
+static void
+listed_names (TpDBusDaemon *proxy,
+              const gchar **names,
+              const GError *error,
+              gpointer user_data,
+              GObject *weak_object)
+{
+  guint which = GPOINTER_TO_UINT (user_data);
+  TpDBusDaemon *want_proxy = NULL;
+  GObject *want_object = NULL;
+
+  if (error == NULL)
+    {
+      g_message ("ListNames() succeeded (first name: %s), according to "
+          "user_data this was on proxy #%d '%c'", *names, which, 'a' + which);
+      tp_intset_add (method_ok, which);
+
+      switch (which)
+        {
+        case TEST_A:
+          want_proxy = a;
+          want_object = (GObject *) z;
+          break;
+        case TEST_C:
+          want_proxy = c;
+          want_object = NULL;
+          break;
+        case TEST_D:
+          want_proxy = copy_of_d;
+          want_object = NULL;
+          break;
+        case TEST_G:
+          want_proxy = copy_of_g;
+          want_object = (GObject *) copy_of_g;
+          break;
+        case TEST_Z:
+          want_proxy = z;
+          want_object = (GObject *) a;
+          break;
+        default:
+          MYASSERT (FALSE, ": %c (%p) method call succeeded, which shouldn't "
+              "happen", 'a' + which, proxy);
+          return;
+        }
+    }
+  else
+    {
+      g_message ("ListNames() failed (%s), according to "
+          "user_data this was on proxy #%d '%c'", error->message,
+          which, 'a' + which);
+      tp_intset_add (method_error, which);
+
+      switch (which)
+        {
+        case TEST_C:
+          want_proxy = c;
+          want_object = NULL;
+          break;
+        case TEST_F:
+          want_proxy = f;
+          want_object = NULL;
+          break;
+        default:
+          MYASSERT (FALSE, ": %c (%p) method call failed, which shouldn't "
+              "happen", 'a' + which, proxy);
+        }
+    }
+
+  MYASSERT (proxy == want_proxy, ": Proxy is %p, expected %p", proxy,
+      want_proxy);
+  MYASSERT (weak_object == want_object, ": Weak object is %p, expected %p",
+      weak_object, want_object);
+
+  if (which == TEST_Z)
+    g_main_loop_quit (mainloop);
+}
+
+static void
+noc (TpDBusDaemon *proxy,
+     const gchar *name,
+     const gchar *old,
+     const gchar *new,
+     gpointer user_data,
+     GObject *weak_object)
+{
+  /* do nothing */
+}
+
+int
+main (int argc,
+      char **argv)
+{
+  GObject *b_stub, *i_stub, *j_stub, *k_stub;
+  GError err = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, "Because I said so" };
+  TpProxyPendingCall *pc;
+  gpointer tmp_obj;
+
+  g_type_init ();
+  tp_debug_set_flags ("all");
+
+  freed_user_data = tp_intset_sized_new (N_DAEMONS);
+  method_ok = tp_intset_sized_new (N_DAEMONS);
+  method_error = tp_intset_sized_new (N_DAEMONS);
+
+  mainloop = g_main_loop_new (NULL, FALSE);
+
+  /* We use TpDBusDaemon because it's a convenient concrete subclass of
+   * TpProxy. */
+  g_message ("Creating proxies");
+  a = tp_dbus_daemon_new (tp_get_bus ());
+  g_message ("a=%p", a);
+  b = tp_dbus_daemon_new (tp_get_bus ());
+  g_message ("b=%p", b);
+  c = tp_dbus_daemon_new (tp_get_bus ());
+  g_message ("c=%p", c);
+  d = tp_dbus_daemon_new (tp_get_bus ());
+  g_message ("d=%p", d);
+  e = tp_dbus_daemon_new (tp_get_bus ());
+  g_message ("e=%p", e);
+  f = tp_dbus_daemon_new (tp_get_bus ());
+  g_message ("f=%p", f);
+  g = tp_dbus_daemon_new (tp_get_bus ());
+  g_message ("g=%p", g);
+  h = tp_dbus_daemon_new (tp_get_bus ());
+  g_message ("h=%p", h);
+  i = tp_dbus_daemon_new (tp_get_bus ());
+  g_message ("i=%p", i);
+  j = tp_dbus_daemon_new (tp_get_bus ());
+  g_message ("j=%p", j);
+  k = tp_dbus_daemon_new (tp_get_bus ());
+  g_message ("k=%p", k);
+  z = tp_dbus_daemon_new (tp_get_bus ());
+  g_message ("z=%p", z);
+
+  /* a survives */
+  g_message ("Starting call on a");
+  tp_cli_dbus_daemon_call_list_names (a, -1, listed_names, PTR (TEST_A),
+      destroy_user_data, (GObject *) z);
+  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_A), "");
+  MYASSERT (!tp_intset_is_member (method_ok, TEST_A), "");
+  MYASSERT (!tp_intset_is_member (method_error, TEST_A), "");
+
+  /* b gets its pending call cancelled because the weak object is
+   * destroyed */
+  b_stub = g_object_new (stub_object_get_type (), NULL);
+  g_message ("Starting call on b");
+  tp_cli_dbus_daemon_call_list_names (b, -1, listed_names, PTR (TEST_B),
+      destroy_user_data, b_stub);
+  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_B), "");
+  g_object_unref (b_stub);
+  MYASSERT (!tp_intset_is_member (method_ok, TEST_B), "");
+  MYASSERT (!tp_intset_is_member (method_error, TEST_B), "");
+
+  /* c is explicitly invalidated for an application-specific reason,
+   * but its call still proceeds */
+  g_message ("Starting call on c");
+  tp_cli_dbus_daemon_call_list_names (c, -1, listed_names, PTR (TEST_C),
+      destroy_user_data, NULL);
+  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_C), "");
+  g_message ("Forcibly invalidating c");
+  tp_proxy_invalidate ((TpProxy *) c, &err);
+  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_C), "");
+  MYASSERT (!tp_intset_is_member (method_ok, TEST_C), "");
+  MYASSERT (!tp_intset_is_member (method_error, TEST_C), "");
+
+  /* d gets unreferenced, but survives long enough for the call to complete
+   * successfully later, because the pending call holds a reference */
+  g_message ("Starting call on d");
+  tp_cli_dbus_daemon_call_list_names (d, -1, listed_names, PTR (TEST_D),
+      destroy_user_data, NULL);
+  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_D), "");
+  g_message ("Unreferencing d");
+  copy_of_d = d;
+  g_object_add_weak_pointer (copy_of_d, &copy_of_d);
+  g_object_unref (d);
+  d = NULL;
+  MYASSERT (copy_of_d != NULL, "");
+  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_D), "");
+  MYASSERT (!tp_intset_is_member (method_ok, TEST_D), "");
+  MYASSERT (!tp_intset_is_member (method_error, TEST_D), "");
+
+  /* e gets its method call cancelled explicitly */
+  g_message ("Starting call on e");
+  pc = tp_cli_dbus_daemon_call_list_names (e, -1, listed_names, PTR (TEST_E),
+      destroy_user_data, NULL);
+  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_E), "");
+  g_message ("Cancelling call on e");
+  tp_proxy_pending_call_cancel (pc);
+  MYASSERT (!tp_intset_is_member (method_ok, TEST_E), "");
+  MYASSERT (!tp_intset_is_member (method_error, TEST_E), "");
+
+  /* f's method call fails with an error, because it's implicitly
+   * invalidated by its DBusGProxy being destroyed.
+   *
+   * Note that this test case exploits implementation details of dbus-glib.
+   * If it stops working after a dbus-glib upgrade, that's probably why. */
+  g_message ("Starting call on f");
+  tp_cli_dbus_daemon_call_list_names (f, -1, listed_names, PTR (TEST_F),
+      destroy_user_data, NULL);
+  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_F), "");
+  g_message ("Forcibly disposing f's DBusGProxy to simulate name owner loss");
+  tmp_obj = tp_proxy_borrow_interface_by_id ((TpProxy *) f,
+      TP_IFACE_QUARK_DBUS_DAEMON, NULL);
+  MYASSERT (tmp_obj != NULL, "");
+  g_object_run_dispose (tmp_obj);
+  /* the callback will be queued (to avoid reentrancy), so we don't get it
+   * until the main loop runs */
+  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_F), "");
+  MYASSERT (!tp_intset_is_member (method_ok, TEST_F), "");
+  MYASSERT (!tp_intset_is_member (method_error, TEST_F), "");
+
+  /* g gets unreferenced, but survives long enough for the call to complete
+   * successfully later, because the pending call holds a reference;
+   * however, unlike case D, here the pending call weakly references the
+   * proxy. This is never necessary, but is an interesting corner case that
+   * should be tested. */
+  g_message ("Starting call on g");
+  tp_cli_dbus_daemon_call_list_names (g, -1, listed_names, PTR (TEST_G),
+      destroy_user_data, (GObject *) g);
+  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_G), "");
+  g_message ("Unreferencing g");
+  copy_of_g = g;
+  g_object_add_weak_pointer (copy_of_g, &copy_of_g);
+  g_object_unref (g);
+  g = NULL;
+  MYASSERT (copy_of_g != NULL, "");
+  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_G), "");
+  MYASSERT (!tp_intset_is_member (method_ok, TEST_G), "");
+  MYASSERT (!tp_intset_is_member (method_error, TEST_G), "");
+
+  /* h gets unreferenced, *and* the call is cancelled (regression test for
+   * fd.o #14576) */
+  g_message ("Starting call on h");
+  pc = tp_cli_dbus_daemon_call_list_names (h, -1, listed_names, PTR (TEST_H),
+      destroy_user_data, NULL);
+  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_H), "");
+  g_message ("Unreferencing h");
+  copy_of_h = h;
+  g_object_add_weak_pointer (copy_of_h, &copy_of_h);
+  g_object_unref (h);
+  h = NULL;
+  MYASSERT (copy_of_h != NULL, "");
+  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_H), "");
+  MYASSERT (!tp_intset_is_member (method_ok, TEST_H), "");
+  MYASSERT (!tp_intset_is_member (method_error, TEST_H), "");
+  g_message ("Cancelling call on h");
+  tp_proxy_pending_call_cancel (pc);
+  MYASSERT (!tp_intset_is_member (method_ok, TEST_H), "");
+  MYASSERT (!tp_intset_is_member (method_error, TEST_H), "");
+
+  /* i gets its pending call cancelled because i_stub is
+   * destroyed, *and* the pending call holds the last reference to it,
+   * *and* there is a signal connection
+   * (used to reproduce fd.o #14750 - see case h in test-disconnection.c
+   * for the minimal regression test) */
+  i_stub = g_object_new (stub_object_get_type (), NULL);
+  tp_cli_dbus_daemon_connect_to_name_owner_changed (i, noc, PTR (TEST_I),
+      NULL, i_stub, NULL);
+  g_message ("Starting call on i");
+  tp_cli_dbus_daemon_call_list_names (i, -1, listed_names, PTR (TEST_I),
+      destroy_user_data, i_stub);
+  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_I), "");
+  tp_cli_dbus_daemon_connect_to_name_owner_changed (i, noc, PTR (TEST_I),
+      NULL, i_stub, NULL);
+  g_message ("Unreferencing i");
+  copy_of_i = i;
+  g_object_add_weak_pointer (copy_of_i, &copy_of_i);
+  g_object_unref (i);
+  i = NULL;
+  MYASSERT (copy_of_i != NULL, "");
+  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_I), "");
+  MYASSERT (!tp_intset_is_member (method_ok, TEST_I), "");
+  MYASSERT (!tp_intset_is_member (method_error, TEST_I), "");
+  g_object_unref (i_stub);
+  MYASSERT (!tp_intset_is_member (method_ok, TEST_I), "");
+  MYASSERT (!tp_intset_is_member (method_error, TEST_I), "");
+
+  /* j gets its pending call cancelled explicitly, and j_stub is
+   * destroyed in response (related to fd.o #14750) */
+  j_stub = g_object_new (stub_object_get_type (), NULL);
+  g_object_weak_ref (j_stub, j_stub_destroyed, PTR (TEST_J));
+  g_message ("Starting call on j");
+  pc = tp_cli_dbus_daemon_call_list_names (j, -1, listed_names, j_stub,
+      g_object_unref, j_stub);
+  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_J), "");
+  g_message ("Cancelling call on j");
+  tp_proxy_pending_call_cancel (pc);
+  MYASSERT (!tp_intset_is_member (method_ok, TEST_J), "");
+  MYASSERT (!tp_intset_is_member (method_error, TEST_J), "");
+
+  /* k gets its pending call cancelled explicitly because its weak object
+   * is destroyed, meaning there are simultaneously two reasons for it
+   * to become cancelled (equivalent to fd.o#14750, but for pending calls
+   * rather than signal connections) */
+  k_stub = g_object_new (stub_object_get_type (), NULL);
+  g_message ("Starting call on k");
+  g_object_weak_ref (k_stub, k_stub_destroyed, &pc);
+  pc = tp_cli_dbus_daemon_call_list_names (k, -1, listed_names, PTR (TEST_K),
+      destroy_user_data, k_stub);
+  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_K), "");
+  MYASSERT (!tp_intset_is_member (method_ok, TEST_K), "");
+  MYASSERT (!tp_intset_is_member (method_error, TEST_K), "");
+  g_object_unref (k_stub);
+  MYASSERT (!tp_intset_is_member (method_ok, TEST_K), "");
+  MYASSERT (!tp_intset_is_member (method_error, TEST_K), "");
+
+  /* z survives too; we assume that method calls succeed in order,
+   * so when z has had its reply, we can stop the main loop */
+  g_message ("Starting call on z");
+  tp_cli_dbus_daemon_call_list_names (z, -1, listed_names, PTR (TEST_Z),
+      destroy_user_data, (GObject *) a);
+  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_Z), "");
+  MYASSERT (!tp_intset_is_member (method_ok, TEST_Z), "");
+  MYASSERT (!tp_intset_is_member (method_error, TEST_Z), "");
+
+  g_message ("Running main loop");
+  g_main_loop_run (mainloop);
+  g_main_loop_unref (mainloop);
+
+  /* now that the calls have been delivered, d will finally have gone away */
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_D), "");
+  MYASSERT (tp_intset_is_member (method_ok, TEST_D), "");
+  MYASSERT (!tp_intset_is_member (method_error, TEST_D), "");
+  MYASSERT (copy_of_d == NULL, "");
+
+  /* ... and g too */
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_G), "");
+  MYASSERT (tp_intset_is_member (method_ok, TEST_G), "");
+  MYASSERT (!tp_intset_is_member (method_error, TEST_G), "");
+  MYASSERT (copy_of_g == NULL, "");
+
+  /* also, F will have been invalidated */
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_F), "");
+  MYASSERT (!tp_intset_is_member (method_ok, TEST_F), "");
+  MYASSERT (tp_intset_is_member (method_error, TEST_F), "");
+
+  /* Now that its call has been cancelled, h will have gone away. Likewise
+   * for i */
+  MYASSERT (copy_of_h == NULL, "");
+  MYASSERT (copy_of_i == NULL, "");
+
+  /* User data for all the cancelled calls has also gone away */
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_B), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_E), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_H), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_I), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_J), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_K), "");
+
+  /* the calls have been delivered to A, C and Z by now */
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_A), "");
+  MYASSERT (tp_intset_is_member (method_ok, TEST_A), "");
+  MYASSERT (!tp_intset_is_member (method_error, TEST_A), "");
+
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_C), "");
+  MYASSERT (tp_intset_is_member (method_ok, TEST_C), "");
+  MYASSERT (!tp_intset_is_member (method_error, TEST_C), "");
+
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_Z), "");
+  MYASSERT (tp_intset_is_member (method_ok, TEST_Z), "");
+  MYASSERT (!tp_intset_is_member (method_error, TEST_Z), "");
+
+  g_message ("Dereferencing remaining proxies");
+  g_object_unref (a);
+  g_object_unref (b);
+  g_object_unref (c);
+  MYASSERT (d == NULL, "");
+  g_object_unref (e);
+  g_object_unref (f);
+  MYASSERT (g == NULL, "");
+  MYASSERT (h == NULL, "");
+  MYASSERT (i == NULL, "");
+  g_object_unref (j);
+  g_object_unref (z);
+
+  /* we should already have checked each of these at least once, but just to
+   * make sure we have a systematic test that all user data is freed... */
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_A), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_B), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_C), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_D), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_E), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_F), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_G), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_H), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_I), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_J), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_K), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_Z), "");
+
+  tp_intset_destroy (freed_user_data);
+  tp_intset_destroy (method_ok);
+  tp_intset_destroy (method_error);
+
+  return 0;
+}
diff --git a/tests/dbus/dbus.c b/tests/dbus/dbus.c
new file mode 100644
index 0000000..d8c6ce8
--- /dev/null
+++ b/tests/dbus/dbus.c
@@ -0,0 +1,247 @@
+#include <dbus/dbus-shared.h>
+#include <glib.h>
+#include <telepathy-glib/dbus.h>
+#include <telepathy-glib/debug.h>
+#include <telepathy-glib/util.h>
+
+#include "tests/lib/myassert.h"
+
+static GPtrArray *events;
+static TpDBusDaemon *bus;
+static GMainLoop *mainloop;
+static gchar *two = "2", *five = "5";
+static gboolean had_owners = FALSE;
+
+static void
+noc (TpDBusDaemon *obj,
+     const gchar *name,
+     const gchar *new_owner,
+     gpointer user_data)
+{
+  const gchar *tag = user_data;
+
+  g_message ("[%s] %s -> <%s>", tag, name, new_owner);
+
+  g_ptr_array_add (events, g_strdup_printf ("[%s] %s %d",
+        tag, name, new_owner[0]));
+
+  if (new_owner[0] != '\0')
+    had_owners = TRUE;
+
+  if (!tp_strdiff (name, "net.example"))
+    {
+      if (new_owner[0] == '\0')
+        {
+          if (had_owners)
+            {
+              g_main_loop_quit (mainloop);
+            }
+          else
+            {
+              guint ret;
+              GError *error = NULL;
+
+              MYASSERT (tp_cli_dbus_daemon_run_request_name (obj, -1,
+                    "com.example", 0, &ret, &error, NULL), "");
+              MYASSERT (ret == 1 && error == NULL, "");
+              MYASSERT (tp_cli_dbus_daemon_run_request_name (obj, -1,
+                    "org.example", 0, &ret, &error, NULL), "");
+              MYASSERT (ret == 1 && error == NULL, "");
+              MYASSERT (tp_cli_dbus_daemon_run_request_name (obj, -1,
+                    "net.example", 0, &ret, &error, NULL), "");
+              MYASSERT (ret == 1 && error == NULL, "");
+            }
+        }
+      else
+        {
+          guint ret;
+          GError *error = NULL;
+
+          MYASSERT (tp_dbus_daemon_cancel_name_owner_watch (obj,
+                "org.example", noc, five), "");
+          MYASSERT (tp_cli_dbus_daemon_run_release_name (obj, -1,
+                "org.example", &ret, &error, NULL), "");
+          MYASSERT (ret == 1 && error == NULL, "");
+          MYASSERT (tp_cli_dbus_daemon_run_release_name (obj, -1,
+                "net.example", &ret, &error, NULL), "");
+          MYASSERT (ret == 1 && error == NULL, "");
+        }
+    }
+}
+
+int
+main (int argc,
+      char **argv)
+{
+  guint i;
+
+  tp_debug_set_flags ("all");
+  mainloop = g_main_loop_new (NULL, FALSE);
+
+  events = g_ptr_array_new ();
+
+  g_type_init ();
+
+  MYASSERT (tp_dbus_check_valid_object_path ("/", NULL), "");
+  MYASSERT (tp_dbus_check_valid_object_path ("/a", NULL), "");
+  MYASSERT (tp_dbus_check_valid_object_path ("/foo", NULL), "");
+  MYASSERT (!tp_dbus_check_valid_object_path ("//", NULL), "");
+  MYASSERT (!tp_dbus_check_valid_object_path ("/a//b", NULL), "");
+  MYASSERT (tp_dbus_check_valid_object_path ("/a/b", NULL), "");
+  MYASSERT (!tp_dbus_check_valid_object_path ("/a/b/", NULL), "");
+  MYASSERT (!tp_dbus_check_valid_object_path ("a/b", NULL), "");
+  MYASSERT (!tp_dbus_check_valid_object_path ("/*a", NULL), "");
+
+#define TEST_LONG_BIT "excessively.long.name.longer.than._255.characters"
+#define TEST_LONG (TEST_LONG_BIT TEST_LONG_BIT TEST_LONG_BIT TEST_LONG_BIT \
+    TEST_LONG_BIT TEST_LONG_BIT TEST_LONG_BIT TEST_LONG_BIT)
+
+  MYASSERT (!tp_dbus_check_valid_member_name ("", NULL), "");
+  MYASSERT (!tp_dbus_check_valid_member_name ("123abc", NULL), "");
+  MYASSERT (!tp_dbus_check_valid_member_name ("a.b", NULL), "");
+  MYASSERT (!tp_dbus_check_valid_member_name ("a*b", NULL), "");
+  MYASSERT (tp_dbus_check_valid_member_name ("example", NULL), "");
+  MYASSERT (tp_dbus_check_valid_member_name ("_1", NULL), "");
+
+  MYASSERT (!tp_dbus_check_valid_interface_name ("", NULL), "");
+  MYASSERT (!tp_dbus_check_valid_interface_name (TEST_LONG, NULL), "");
+  MYASSERT (!tp_dbus_check_valid_interface_name ("hasnodot", NULL), "");
+  MYASSERT (!tp_dbus_check_valid_interface_name ("123abc.example", NULL), "");
+  MYASSERT (!tp_dbus_check_valid_interface_name ("com.1", NULL), "");
+  MYASSERT (!tp_dbus_check_valid_interface_name ("com.e*ample", NULL), "");
+  MYASSERT (!tp_dbus_check_valid_interface_name ("com..example", NULL), "");
+  MYASSERT (!tp_dbus_check_valid_interface_name (".com.example", NULL), "");
+  MYASSERT (!tp_dbus_check_valid_interface_name ("com.example.", NULL), "");
+  MYASSERT (tp_dbus_check_valid_interface_name ("com.example", NULL), "");
+  MYASSERT (tp_dbus_check_valid_interface_name ("com._1", NULL), "");
+
+  MYASSERT (tp_dbus_check_valid_bus_name (":1.1", TP_DBUS_NAME_TYPE_ANY,
+        NULL), "");
+  MYASSERT (tp_dbus_check_valid_bus_name ("com.example", TP_DBUS_NAME_TYPE_ANY,
+        NULL), "");
+  MYASSERT (tp_dbus_check_valid_bus_name (DBUS_SERVICE_DBUS,
+        TP_DBUS_NAME_TYPE_ANY, NULL), "");
+
+  MYASSERT (tp_dbus_check_valid_bus_name (":1.1",
+        TP_DBUS_NAME_TYPE_NOT_BUS_DAEMON, NULL), "");
+  MYASSERT (tp_dbus_check_valid_bus_name ("com.example",
+        TP_DBUS_NAME_TYPE_NOT_BUS_DAEMON, NULL), "");
+  MYASSERT (!tp_dbus_check_valid_bus_name (DBUS_SERVICE_DBUS,
+        TP_DBUS_NAME_TYPE_NOT_BUS_DAEMON, NULL), "");
+
+  MYASSERT (!tp_dbus_check_valid_bus_name (":1.1",
+        TP_DBUS_NAME_TYPE_BUS_DAEMON, NULL), "");
+  MYASSERT (!tp_dbus_check_valid_bus_name ("com.example",
+        TP_DBUS_NAME_TYPE_BUS_DAEMON, NULL), "");
+  MYASSERT (tp_dbus_check_valid_bus_name (DBUS_SERVICE_DBUS,
+        TP_DBUS_NAME_TYPE_BUS_DAEMON, NULL), "");
+
+  MYASSERT (!tp_dbus_check_valid_bus_name (":1.1",
+        TP_DBUS_NAME_TYPE_WELL_KNOWN, NULL), "");
+  MYASSERT (tp_dbus_check_valid_bus_name ("com.example",
+        TP_DBUS_NAME_TYPE_WELL_KNOWN, NULL), "");
+  MYASSERT (!tp_dbus_check_valid_bus_name (DBUS_SERVICE_DBUS,
+        TP_DBUS_NAME_TYPE_WELL_KNOWN, NULL), "");
+
+  MYASSERT (tp_dbus_check_valid_bus_name (":1.1",
+        TP_DBUS_NAME_TYPE_UNIQUE, NULL), "");
+  MYASSERT (!tp_dbus_check_valid_bus_name ("com.example",
+        TP_DBUS_NAME_TYPE_UNIQUE, NULL), "");
+  MYASSERT (!tp_dbus_check_valid_bus_name (DBUS_SERVICE_DBUS,
+        TP_DBUS_NAME_TYPE_UNIQUE, NULL), "");
+
+  MYASSERT (tp_dbus_check_valid_bus_name ("com._1",
+        TP_DBUS_NAME_TYPE_ANY, NULL), "");
+  MYASSERT (!tp_dbus_check_valid_bus_name ("",
+        TP_DBUS_NAME_TYPE_ANY, NULL), "");
+  MYASSERT (!tp_dbus_check_valid_bus_name (TEST_LONG,
+        TP_DBUS_NAME_TYPE_ANY, NULL), "");
+  MYASSERT (!tp_dbus_check_valid_bus_name ("hasnodot",
+        TP_DBUS_NAME_TYPE_ANY, NULL), "");
+  MYASSERT (!tp_dbus_check_valid_bus_name ("123abc.example",
+        TP_DBUS_NAME_TYPE_ANY, NULL), "");
+  MYASSERT (!tp_dbus_check_valid_bus_name ("com.1",
+        TP_DBUS_NAME_TYPE_ANY, NULL), "");
+  MYASSERT (!tp_dbus_check_valid_bus_name ("com.e*ample",
+        TP_DBUS_NAME_TYPE_ANY, NULL), "");
+  MYASSERT (!tp_dbus_check_valid_bus_name ("com..example",
+        TP_DBUS_NAME_TYPE_ANY, NULL), "");
+  MYASSERT (!tp_dbus_check_valid_bus_name (".com.example",
+        TP_DBUS_NAME_TYPE_ANY, NULL), "");
+  MYASSERT (!tp_dbus_check_valid_bus_name ("com.example.",
+        TP_DBUS_NAME_TYPE_ANY, NULL), "");
+  MYASSERT (!tp_dbus_check_valid_bus_name (":1.1.",
+        TP_DBUS_NAME_TYPE_ANY, NULL), "");
+
+  bus = tp_dbus_daemon_new (tp_get_bus ());
+
+  /* Regression test for properties */
+    {
+      gchar *bus_name;
+      gchar *object_path;
+      DBusGConnection *dbus_conn;
+
+      g_object_get (bus,
+          "dbus-connection", &dbus_conn,
+          "bus-name", &bus_name,
+          "object-path", &object_path,
+          NULL);
+
+      MYASSERT (object_path != NULL, "");
+      MYASSERT (object_path[0] == '/', "%s", object_path);
+      MYASSERT (bus_name != NULL, "");
+      MYASSERT (!tp_strdiff (bus_name, "org.freedesktop.DBus"),
+            "%s", bus_name);
+      MYASSERT (dbus_conn != NULL, "");
+      MYASSERT (dbus_conn == tp_get_bus (), "%p != %p", dbus_conn,
+          tp_get_bus ());
+
+      g_free (bus_name);
+      g_free (object_path);
+      dbus_g_connection_unref (dbus_conn);
+    }
+
+  tp_dbus_daemon_watch_name_owner (bus, "com.example", noc, "1", NULL);
+  tp_dbus_daemon_watch_name_owner (bus, "com.example", noc, two, NULL);
+  tp_dbus_daemon_watch_name_owner (bus, "com.example", noc, "3", NULL);
+  tp_dbus_daemon_cancel_name_owner_watch (bus, "com.example", noc, two);
+  tp_dbus_daemon_watch_name_owner (bus, "net.example", noc, "4", NULL);
+  tp_dbus_daemon_watch_name_owner (bus, "org.example", noc, five, NULL);
+
+  g_main_loop_run (mainloop);
+
+  MYASSERT (events->len == 9, "");
+
+  /* 58 == ':' - i.e. the beginning of a unique name */
+  MYASSERT (!tp_strdiff (g_ptr_array_index (events, 0),
+        "[1] com.example 0"), "");
+  MYASSERT (!tp_strdiff (g_ptr_array_index (events, 1),
+        "[3] com.example 0"), "");
+  MYASSERT (!tp_strdiff (g_ptr_array_index (events, 2),
+        "[4] net.example 0"), "");
+  MYASSERT (!tp_strdiff (g_ptr_array_index (events, 3),
+        "[5] org.example 0"), "");
+
+  MYASSERT (!tp_strdiff (g_ptr_array_index (events, 4),
+        "[1] com.example 58"), "");
+  MYASSERT (!tp_strdiff (g_ptr_array_index (events, 5),
+        "[3] com.example 58"), "");
+  MYASSERT (!tp_strdiff (g_ptr_array_index (events, 6),
+        "[5] org.example 58"), "");
+  MYASSERT (!tp_strdiff (g_ptr_array_index (events, 7),
+        "[4] net.example 58"), "");
+  MYASSERT (!tp_strdiff (g_ptr_array_index (events, 8),
+        "[4] net.example 0"), "");
+
+  /* keep valgrind happy, at least in the successful case */
+  for (i = 0; i < events->len; i++)
+    {
+      g_free (events->pdata[i]);
+    }
+
+  g_ptr_array_free (events, TRUE);
+  g_main_loop_unref (mainloop);
+  mainloop = NULL;
+
+  return 0;
+}
diff --git a/tests/dbus/disconnection.c b/tests/dbus/disconnection.c
new file mode 100644
index 0000000..815f6aa
--- /dev/null
+++ b/tests/dbus/disconnection.c
@@ -0,0 +1,376 @@
+#include <telepathy-glib/dbus.h>
+#include <telepathy-glib/debug.h>
+#include <telepathy-glib/errors.h>
+#include <telepathy-glib/interfaces.h>
+#include <telepathy-glib/intset.h>
+#include <telepathy-glib/proxy-subclass.h>    /* for _invalidated etc. */
+#include <telepathy-glib/util.h>
+
+#include "tests/lib/myassert.h"
+#include "tests/lib/stub-object.h"
+#include "tests/lib/util.h"
+
+/* just for convenience, since it's used a lot */
+#define PTR(ui) GUINT_TO_POINTER(ui)
+
+/* state tracking */
+static GMainLoop *mainloop;
+static TpDBusDaemon *a;
+static TpDBusDaemon *b;
+static TpDBusDaemon *c;
+static TpDBusDaemon *d;
+static TpDBusDaemon *e;
+static TpDBusDaemon *f;
+static TpDBusDaemon *g;
+static TpDBusDaemon *h;
+static TpDBusDaemon *z;
+static TpIntSet *caught_signal;
+static TpIntSet *freed_user_data;
+
+enum {
+    TEST_A,
+    TEST_B,
+    TEST_C,
+    TEST_D,
+    TEST_E,
+    TEST_F,
+    TEST_G,
+    TEST_H,
+    TEST_Z = 25,
+    N_DAEMONS
+};
+
+static void
+h_stub_destroyed (gpointer data,
+                  GObject *stub)
+{
+  TpProxySignalConnection **p = data;
+
+  tp_proxy_signal_connection_disconnect (*p);
+}
+
+static void
+destroy_user_data (gpointer user_data)
+{
+  guint which = GPOINTER_TO_UINT (user_data);
+  g_message ("User data %c destroyed", 'A' + which);
+  MYASSERT (!tp_intset_is_member (freed_user_data, which), "");
+  tp_intset_add (freed_user_data, which);
+}
+
+static void
+requested_name (TpDBusDaemon *proxy,
+                guint result,
+                const GError *error,
+                gpointer user_data,
+                GObject *weak_object)
+{
+  g_message ("RequestName raised %s",
+      (error == NULL ? "no error" : error->message));
+  /* we're on a private bus, so certainly nobody else should own this name */
+  test_assert_no_error (error);
+  MYASSERT (result == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER, ": %u", result);
+}
+
+static void
+prop_changed (TpProxy *proxy,
+              const GPtrArray *properties,
+              gpointer user_data,
+              GObject *weak_object)
+{
+  g_error ("prop_changed called - a signal connection which should have "
+      "failed has succeeded. Args: proxy=%p user_data=%p", proxy, user_data);
+}
+
+static void
+dummy_noc (TpDBusDaemon *proxy,
+           const gchar *name,
+           const gchar *old,
+           const gchar *new,
+           gpointer user_data,
+           GObject *weak_object)
+{
+  g_error ("dummy_noc called - a signal connection which should have "
+      "failed has succeeded. Args: proxy=%p user_data=%p", proxy, user_data);
+}
+
+static void
+noc (TpDBusDaemon *proxy,
+     const gchar *name,
+     const gchar *old,
+     const gchar *new,
+     gpointer user_data,
+     GObject *weak_object)
+{
+  guint which = GPOINTER_TO_UINT (user_data);
+  TpDBusDaemon *want_proxy = NULL;
+  GObject *want_object = NULL;
+
+  g_message ("Caught signal (%s: %s -> %s) with proxy #%d '%c' according to "
+      "user_data", name, old, new, which, 'a' + which);
+  g_message ("Proxy is %p, weak object is %p", proxy,
+      weak_object);
+  tp_intset_add (caught_signal, which);
+
+  switch (which)
+    {
+    case TEST_A:
+      want_proxy = a;
+      want_object = (GObject *) z;
+      break;
+    case TEST_Z:
+      want_proxy = z;
+      want_object = (GObject *) a;
+      break;
+    default:
+      g_error ("%c (%p) got the signal, which shouldn't have happened",
+          'a' + which, proxy);
+    }
+
+  g_message ("Expecting proxy %p, weak object %p", want_proxy, want_object);
+
+  MYASSERT (proxy == want_proxy, ": %p != %p", proxy, want_proxy);
+  MYASSERT (weak_object == want_object, ": %p != %p", weak_object,
+      want_object);
+
+  if (tp_intset_is_member (caught_signal, TEST_A) &&
+      tp_intset_is_member (caught_signal, TEST_Z))
+    {
+      /* we've had all the signals we're going to */
+      g_main_loop_quit (mainloop);
+    }
+}
+
+static void
+set_freed (gpointer user_data)
+{
+  gboolean *boolptr = user_data;
+
+  MYASSERT (*boolptr == FALSE, "");
+  *boolptr = TRUE;
+}
+
+int
+main (int argc,
+      char **argv)
+{
+  GObject *stub;
+  GError *error_out = NULL;
+  GError err = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, "Because I said so" };
+  TpProxySignalConnection *sc;
+  gpointer tmp_obj;
+  gboolean freed = FALSE;
+
+  g_type_init ();
+  tp_debug_set_flags ("all");
+
+  freed_user_data = tp_intset_sized_new (N_DAEMONS);
+  caught_signal = tp_intset_sized_new (N_DAEMONS);
+
+  mainloop = g_main_loop_new (NULL, FALSE);
+
+  /* We use TpDBusDaemon because it's a convenient concrete subclass of
+   * TpProxy. */
+  g_message ("Creating proxies");
+  a = tp_dbus_daemon_new (tp_get_bus ());
+  g_message ("a=%p", a);
+  b = tp_dbus_daemon_new (tp_get_bus ());
+  g_message ("b=%p", b);
+  c = tp_dbus_daemon_new (tp_get_bus ());
+  g_message ("c=%p", c);
+  d = tp_dbus_daemon_new (tp_get_bus ());
+  g_message ("d=%p", d);
+  e = tp_dbus_daemon_new (tp_get_bus ());
+  g_message ("e=%p", e);
+  f = tp_dbus_daemon_new (tp_get_bus ());
+  g_message ("f=%p", f);
+  g = tp_dbus_daemon_new (tp_get_bus ());
+  g_message ("g=%p", g);
+  h = tp_dbus_daemon_new (tp_get_bus ());
+  g_message ("h=%p", h);
+  z = tp_dbus_daemon_new (tp_get_bus ());
+  g_message ("z=%p", z);
+
+  /* a survives */
+  g_message ("Connecting signal to a");
+  tp_cli_dbus_daemon_connect_to_name_owner_changed (a, noc, PTR (TEST_A),
+      destroy_user_data, (GObject *) z, &error_out);
+  test_assert_no_error (error_out);
+
+  /* assert that connecting to a signal on an interface we don't have fails */
+  freed = FALSE;
+  tp_cli_properties_interface_connect_to_properties_changed (a, prop_changed,
+      &freed, set_freed, NULL, &error_out);
+  MYASSERT (freed, "");
+  MYASSERT (error_out != NULL, "");
+  MYASSERT (error_out->code == TP_DBUS_ERROR_NO_INTERFACE, "");
+  g_error_free (error_out);
+  error_out = NULL;
+
+  /* b gets its signal connection cancelled because stub is
+   * destroyed */
+  stub = g_object_new (stub_object_get_type (), NULL);
+  g_message ("Connecting signal to b");
+  tp_cli_dbus_daemon_connect_to_name_owner_changed (b, noc, PTR (TEST_B),
+      destroy_user_data, stub, &error_out);
+  test_assert_no_error (error_out);
+  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_B), "");
+  g_object_unref (stub);
+
+  /* c gets its signal connection cancelled because it's explicitly
+   * invalidated */
+  g_message ("Connecting signal to c");
+  tp_cli_dbus_daemon_connect_to_name_owner_changed (c, noc, PTR (TEST_C),
+      destroy_user_data, NULL, &error_out);
+  test_assert_no_error (error_out);
+  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_C), "");
+  g_message ("Forcibly invalidating c");
+  tp_proxy_invalidate ((TpProxy *) c, &err);
+  /* assert that connecting to a signal on an invalid proxy fails */
+  freed = FALSE;
+  tp_cli_dbus_daemon_connect_to_name_owner_changed (c, dummy_noc, &freed,
+      set_freed, NULL, &error_out);
+  MYASSERT (freed, "");
+  MYASSERT (error_out != NULL, "");
+  g_message ("%d: %d: %s", error_out->domain, error_out->code,
+      error_out->message);
+  MYASSERT (error_out->code == err.code, "%d != %d", error_out->code,
+      err.code);
+  g_error_free (error_out);
+  error_out = NULL;
+
+  /* d gets its signal connection cancelled because it's
+   * implicitly invalidated by being destroyed */
+  g_message ("Connecting signal to d");
+  tp_cli_dbus_daemon_connect_to_name_owner_changed (d, noc, PTR (TEST_D),
+      destroy_user_data, NULL, &error_out);
+  test_assert_no_error (error_out);
+  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_D), "");
+  g_message ("Destroying d");
+  tmp_obj = d;
+  g_object_add_weak_pointer (tmp_obj, &tmp_obj);
+  g_object_unref (d);
+  MYASSERT (tmp_obj == NULL, "");
+  d = NULL;
+
+  /* e gets its signal connection cancelled explicitly */
+  g_message ("Connecting signal to e");
+  sc = tp_cli_dbus_daemon_connect_to_name_owner_changed (e, noc, PTR (TEST_E),
+      destroy_user_data, NULL, &error_out);
+  test_assert_no_error (error_out);
+  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_E), "");
+  g_message ("Disconnecting signal from e");
+  tp_proxy_signal_connection_disconnect (sc);
+
+  /* f gets its signal connection cancelled because it's implicitly
+   * invalidated by its DBusGProxy being destroyed.
+   *
+   * Note that this test case exploits implementation details of dbus-glib.
+   * If it stops working after a dbus-glib upgrade, that's probably why. */
+  g_message ("Connecting signal to f");
+  tp_cli_dbus_daemon_connect_to_name_owner_changed (f, noc, PTR (TEST_F),
+      destroy_user_data, NULL, &error_out);
+  test_assert_no_error (error_out);
+  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_F), "");
+  g_message ("Forcibly disposing f's DBusGProxy to simulate name owner loss");
+  tmp_obj = tp_proxy_borrow_interface_by_id ((TpProxy *) f,
+      TP_IFACE_QUARK_DBUS_DAEMON, NULL);
+  MYASSERT (tmp_obj != NULL, "");
+  g_object_run_dispose (tmp_obj);
+  /* assert that connecting to a signal on an invalid proxy fails */
+  freed = FALSE;
+  tp_cli_dbus_daemon_connect_to_name_owner_changed (f, dummy_noc, &freed,
+      set_freed, NULL, &error_out);
+  MYASSERT (freed, "");
+  MYASSERT (error_out != NULL, "");
+  MYASSERT (error_out->code == DBUS_GERROR_NAME_HAS_NO_OWNER, "");
+  g_error_free (error_out);
+  error_out = NULL;
+
+  /* g gets its signal connection cancelled because it's
+   * implicitly invalidated by being destroyed; unlike d, the signal
+   * connection weakly references the proxy. This is never necessary, but is
+   * an interesting corner case that should be tested. */
+  g_message ("Connecting signal to g");
+  tp_cli_dbus_daemon_connect_to_name_owner_changed (g, noc, PTR (TEST_G),
+      destroy_user_data, (GObject *) g, &error_out);
+  test_assert_no_error (error_out);
+  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_G), "");
+  g_message ("Destroying g");
+  tmp_obj = g;
+  g_object_add_weak_pointer (tmp_obj, &tmp_obj);
+  g_object_unref (g);
+  MYASSERT (tmp_obj == NULL, "");
+  g = NULL;
+
+  /* h gets its signal connection cancelled because its weak object is
+   * destroyed, meaning there are simultaneously two reasons for it to become
+   * cancelled (fd.o#14750) */
+  stub = g_object_new (stub_object_get_type (), NULL);
+  g_object_weak_ref (stub, h_stub_destroyed, &sc);
+  g_message ("Connecting signal to h");
+  sc = tp_cli_dbus_daemon_connect_to_name_owner_changed (h, noc, PTR (TEST_H),
+      destroy_user_data, stub, &error_out);
+  test_assert_no_error (error_out);
+  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_H), "");
+  g_object_unref (stub);
+
+  /* z survives; we assume that the signals are delivered in either
+   * forward or reverse order, so if both a and z have had their signal, we
+   * can stop the main loop */
+  g_message ("Connecting signal to z");
+  tp_cli_dbus_daemon_connect_to_name_owner_changed (z, noc, PTR (TEST_Z),
+      destroy_user_data, (GObject *) a, &error_out);
+  test_assert_no_error (error_out);
+
+  /* make sure a NameOwnerChanged signal occurs */
+  g_message ("Requesting name");
+  tp_cli_dbus_daemon_call_request_name (a, -1, "com.example.NameTest",
+      0, requested_name, NULL, NULL, NULL);
+
+  g_message ("Running main loop");
+  g_main_loop_run (mainloop);
+  g_main_loop_unref (mainloop);
+
+  /* Now that the main loop has run, cancelled signal connections have been
+   * freed */
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_B), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_C), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_D), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_E), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_F), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_G), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_H), "");
+
+  /* both A and Z are still listening for signals, so their user data is
+   * still held */
+  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_A), "");
+  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_Z), "");
+
+  g_message ("Dereferencing remaining proxies");
+  g_object_unref (a);
+  g_object_unref (b);
+  g_object_unref (c);
+  MYASSERT (d == NULL, "");
+  g_object_unref (e);
+  g_object_unref (f);
+  MYASSERT (g == NULL, "");
+  g_object_unref (z);
+
+  /* we should already have checked each of these at least once, but just to
+   * make sure we have a systematic test that all user data is freed... */
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_A), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_B), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_C), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_D), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_E), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_F), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_G), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_H), "");
+  MYASSERT (tp_intset_is_member (freed_user_data, TEST_Z), "");
+
+  tp_intset_destroy (freed_user_data);
+  tp_intset_destroy (caught_signal);
+
+  return 0;
+}
diff --git a/tests/dbus/example-no-protocols.c b/tests/dbus/example-no-protocols.c
new file mode 100644
index 0000000..201fe64
--- /dev/null
+++ b/tests/dbus/example-no-protocols.c
@@ -0,0 +1,96 @@
+#include <glib-object.h>
+#include <telepathy-glib/connection-manager.h>
+#include <telepathy-glib/debug.h>
+#include <telepathy-glib/defs.h>
+#include <telepathy-glib/errors.h>
+
+static void
+prepare (void)
+{
+  GError *error = NULL;
+  const gchar *abs_top_builddir = g_getenv ("abs_top_builddir");
+  gchar *command[] = {
+      g_strdup_printf ("%s/%s",
+          abs_top_builddir,
+          "examples/cm/no-protocols/telepathy-example-no-protocols"),
+      NULL
+  };
+
+  g_assert (abs_top_builddir != NULL);
+
+  if (!g_spawn_async (NULL, command, NULL, 0, NULL, NULL, NULL, &error))
+    {
+      g_error ("g_spawn_async: %s", error->message);
+    }
+
+  g_free (command[0]);
+}
+
+static void
+connection_manager_got_info (TpConnectionManager *cm,
+                             guint source,
+                             GMainLoop *mainloop)
+{
+  GHashTable *empty = g_hash_table_new (NULL, NULL);
+  gchar *bus_name = NULL;
+  gchar *object_path = NULL;
+  GError *error = NULL;
+
+  g_message ("Emitted got-info (source=%d)", source);
+
+  if (source < TP_CM_INFO_SOURCE_LIVE)
+    return;
+
+  tp_cli_connection_manager_run_request_connection (cm, -1,
+      "jabber", empty, &bus_name, &object_path, &error, NULL);
+
+  g_assert (error != NULL);
+  g_assert (error->domain == TP_ERRORS);
+  g_assert (error->code == TP_ERROR_NOT_IMPLEMENTED);
+
+  g_error_free (error);
+
+  g_main_loop_quit (mainloop);
+
+  g_hash_table_destroy (empty);
+}
+
+static gboolean
+time_out (gpointer mainloop)
+{
+  g_error ("Timed out");
+  g_assert_not_reached ();
+  return FALSE;
+}
+
+int
+main (int argc,
+      char **argv)
+{
+  GMainLoop *mainloop;
+  TpConnectionManager *cm;
+
+  prepare ();
+
+  g_type_init ();
+
+  tp_debug_set_flags ("all");
+
+  mainloop = g_main_loop_new (NULL, FALSE);
+
+  cm = tp_connection_manager_new (tp_dbus_daemon_new (tp_get_bus ()),
+      "example_no_protocols", NULL, NULL);
+  g_assert (cm != NULL);
+
+  g_signal_connect (cm, "got-info",
+      G_CALLBACK (connection_manager_got_info), mainloop);
+
+  g_timeout_add (5000, time_out, mainloop);
+
+  g_main_loop_run (mainloop);
+
+  g_object_unref (cm);
+  g_main_loop_unref (mainloop);
+
+  return 0;
+}
diff --git a/tests/dbus/test-call-cancellation.c b/tests/dbus/test-call-cancellation.c
deleted file mode 100644
index 5f66b45..0000000
--- a/tests/dbus/test-call-cancellation.c
+++ /dev/null
@@ -1,472 +0,0 @@
-#include <telepathy-glib/dbus.h>
-#include <telepathy-glib/debug.h>
-#include <telepathy-glib/errors.h>
-#include <telepathy-glib/interfaces.h>
-#include <telepathy-glib/intset.h>
-#include <telepathy-glib/proxy-subclass.h>    /* for _invalidated etc. */
-#include <telepathy-glib/util.h>
-
-#include "tests/lib/myassert.h"
-#include "tests/lib/stub-object.h"
-
-/* just for convenience, since it's used a lot */
-#define PTR(ui) GUINT_TO_POINTER(ui)
-
-/* state tracking */
-static GMainLoop *mainloop;
-static TpDBusDaemon *a;
-static TpDBusDaemon *b;
-static TpDBusDaemon *c;
-static TpDBusDaemon *d;
-static TpDBusDaemon *e;
-static TpDBusDaemon *f;
-static TpDBusDaemon *g;
-static TpDBusDaemon *h;
-static TpDBusDaemon *i;
-static TpDBusDaemon *j;
-static TpDBusDaemon *k;
-static TpDBusDaemon *z;
-static TpIntSet *method_ok;
-static TpIntSet *method_error;
-static TpIntSet *freed_user_data;
-static gpointer copy_of_d;
-static gpointer copy_of_g;
-static gpointer copy_of_h;
-static gpointer copy_of_i;
-
-enum {
-    TEST_A,
-    TEST_B,
-    TEST_C,
-    TEST_D,
-    TEST_E,
-    TEST_F,
-    TEST_G,
-    TEST_H,
-    TEST_I,
-    TEST_J,
-    TEST_K,
-    TEST_Z = 25,
-    N_DAEMONS
-};
-
-static void
-destroy_user_data (gpointer user_data)
-{
-  guint which = GPOINTER_TO_UINT (user_data);
-  g_message ("User data %c destroyed", 'A' + which);
-  tp_intset_add (freed_user_data, which);
-}
-
-static void
-j_stub_destroyed (gpointer data,
-                  GObject *stub)
-{
-  destroy_user_data (data);
-}
-
-static void
-k_stub_destroyed (gpointer data,
-                  GObject *stub)
-{
-  TpProxyPendingCall **p = data;
-
-  tp_proxy_pending_call_cancel (*p);
-}
-
-static void
-listed_names (TpDBusDaemon *proxy,
-              const gchar **names,
-              const GError *error,
-              gpointer user_data,
-              GObject *weak_object)
-{
-  guint which = GPOINTER_TO_UINT (user_data);
-  TpDBusDaemon *want_proxy = NULL;
-  GObject *want_object = NULL;
-
-  if (error == NULL)
-    {
-      g_message ("ListNames() succeeded (first name: %s), according to "
-          "user_data this was on proxy #%d '%c'", *names, which, 'a' + which);
-      tp_intset_add (method_ok, which);
-
-      switch (which)
-        {
-        case TEST_A:
-          want_proxy = a;
-          want_object = (GObject *) z;
-          break;
-        case TEST_C:
-          want_proxy = c;
-          want_object = NULL;
-          break;
-        case TEST_D:
-          want_proxy = copy_of_d;
-          want_object = NULL;
-          break;
-        case TEST_G:
-          want_proxy = copy_of_g;
-          want_object = (GObject *) copy_of_g;
-          break;
-        case TEST_Z:
-          want_proxy = z;
-          want_object = (GObject *) a;
-          break;
-        default:
-          MYASSERT (FALSE, ": %c (%p) method call succeeded, which shouldn't "
-              "happen", 'a' + which, proxy);
-          return;
-        }
-    }
-  else
-    {
-      g_message ("ListNames() failed (%s), according to "
-          "user_data this was on proxy #%d '%c'", error->message,
-          which, 'a' + which);
-      tp_intset_add (method_error, which);
-
-      switch (which)
-        {
-        case TEST_C:
-          want_proxy = c;
-          want_object = NULL;
-          break;
-        case TEST_F:
-          want_proxy = f;
-          want_object = NULL;
-          break;
-        default:
-          MYASSERT (FALSE, ": %c (%p) method call failed, which shouldn't "
-              "happen", 'a' + which, proxy);
-        }
-    }
-
-  MYASSERT (proxy == want_proxy, ": Proxy is %p, expected %p", proxy,
-      want_proxy);
-  MYASSERT (weak_object == want_object, ": Weak object is %p, expected %p",
-      weak_object, want_object);
-
-  if (which == TEST_Z)
-    g_main_loop_quit (mainloop);
-}
-
-static void
-noc (TpDBusDaemon *proxy,
-     const gchar *name,
-     const gchar *old,
-     const gchar *new,
-     gpointer user_data,
-     GObject *weak_object)
-{
-  /* do nothing */
-}
-
-int
-main (int argc,
-      char **argv)
-{
-  GObject *b_stub, *i_stub, *j_stub, *k_stub;
-  GError err = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, "Because I said so" };
-  TpProxyPendingCall *pc;
-  gpointer tmp_obj;
-
-  g_type_init ();
-  tp_debug_set_flags ("all");
-
-  freed_user_data = tp_intset_sized_new (N_DAEMONS);
-  method_ok = tp_intset_sized_new (N_DAEMONS);
-  method_error = tp_intset_sized_new (N_DAEMONS);
-
-  mainloop = g_main_loop_new (NULL, FALSE);
-
-  /* We use TpDBusDaemon because it's a convenient concrete subclass of
-   * TpProxy. */
-  g_message ("Creating proxies");
-  a = tp_dbus_daemon_new (tp_get_bus ());
-  g_message ("a=%p", a);
-  b = tp_dbus_daemon_new (tp_get_bus ());
-  g_message ("b=%p", b);
-  c = tp_dbus_daemon_new (tp_get_bus ());
-  g_message ("c=%p", c);
-  d = tp_dbus_daemon_new (tp_get_bus ());
-  g_message ("d=%p", d);
-  e = tp_dbus_daemon_new (tp_get_bus ());
-  g_message ("e=%p", e);
-  f = tp_dbus_daemon_new (tp_get_bus ());
-  g_message ("f=%p", f);
-  g = tp_dbus_daemon_new (tp_get_bus ());
-  g_message ("g=%p", g);
-  h = tp_dbus_daemon_new (tp_get_bus ());
-  g_message ("h=%p", h);
-  i = tp_dbus_daemon_new (tp_get_bus ());
-  g_message ("i=%p", i);
-  j = tp_dbus_daemon_new (tp_get_bus ());
-  g_message ("j=%p", j);
-  k = tp_dbus_daemon_new (tp_get_bus ());
-  g_message ("k=%p", k);
-  z = tp_dbus_daemon_new (tp_get_bus ());
-  g_message ("z=%p", z);
-
-  /* a survives */
-  g_message ("Starting call on a");
-  tp_cli_dbus_daemon_call_list_names (a, -1, listed_names, PTR (TEST_A),
-      destroy_user_data, (GObject *) z);
-  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_A), "");
-  MYASSERT (!tp_intset_is_member (method_ok, TEST_A), "");
-  MYASSERT (!tp_intset_is_member (method_error, TEST_A), "");
-
-  /* b gets its pending call cancelled because the weak object is
-   * destroyed */
-  b_stub = g_object_new (stub_object_get_type (), NULL);
-  g_message ("Starting call on b");
-  tp_cli_dbus_daemon_call_list_names (b, -1, listed_names, PTR (TEST_B),
-      destroy_user_data, b_stub);
-  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_B), "");
-  g_object_unref (b_stub);
-  MYASSERT (!tp_intset_is_member (method_ok, TEST_B), "");
-  MYASSERT (!tp_intset_is_member (method_error, TEST_B), "");
-
-  /* c is explicitly invalidated for an application-specific reason,
-   * but its call still proceeds */
-  g_message ("Starting call on c");
-  tp_cli_dbus_daemon_call_list_names (c, -1, listed_names, PTR (TEST_C),
-      destroy_user_data, NULL);
-  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_C), "");
-  g_message ("Forcibly invalidating c");
-  tp_proxy_invalidate ((TpProxy *) c, &err);
-  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_C), "");
-  MYASSERT (!tp_intset_is_member (method_ok, TEST_C), "");
-  MYASSERT (!tp_intset_is_member (method_error, TEST_C), "");
-
-  /* d gets unreferenced, but survives long enough for the call to complete
-   * successfully later, because the pending call holds a reference */
-  g_message ("Starting call on d");
-  tp_cli_dbus_daemon_call_list_names (d, -1, listed_names, PTR (TEST_D),
-      destroy_user_data, NULL);
-  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_D), "");
-  g_message ("Unreferencing d");
-  copy_of_d = d;
-  g_object_add_weak_pointer (copy_of_d, &copy_of_d);
-  g_object_unref (d);
-  d = NULL;
-  MYASSERT (copy_of_d != NULL, "");
-  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_D), "");
-  MYASSERT (!tp_intset_is_member (method_ok, TEST_D), "");
-  MYASSERT (!tp_intset_is_member (method_error, TEST_D), "");
-
-  /* e gets its method call cancelled explicitly */
-  g_message ("Starting call on e");
-  pc = tp_cli_dbus_daemon_call_list_names (e, -1, listed_names, PTR (TEST_E),
-      destroy_user_data, NULL);
-  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_E), "");
-  g_message ("Cancelling call on e");
-  tp_proxy_pending_call_cancel (pc);
-  MYASSERT (!tp_intset_is_member (method_ok, TEST_E), "");
-  MYASSERT (!tp_intset_is_member (method_error, TEST_E), "");
-
-  /* f's method call fails with an error, because it's implicitly
-   * invalidated by its DBusGProxy being destroyed.
-   *
-   * Note that this test case exploits implementation details of dbus-glib.
-   * If it stops working after a dbus-glib upgrade, that's probably why. */
-  g_message ("Starting call on f");
-  tp_cli_dbus_daemon_call_list_names (f, -1, listed_names, PTR (TEST_F),
-      destroy_user_data, NULL);
-  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_F), "");
-  g_message ("Forcibly disposing f's DBusGProxy to simulate name owner loss");
-  tmp_obj = tp_proxy_borrow_interface_by_id ((TpProxy *) f,
-      TP_IFACE_QUARK_DBUS_DAEMON, NULL);
-  MYASSERT (tmp_obj != NULL, "");
-  g_object_run_dispose (tmp_obj);
-  /* the callback will be queued (to avoid reentrancy), so we don't get it
-   * until the main loop runs */
-  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_F), "");
-  MYASSERT (!tp_intset_is_member (method_ok, TEST_F), "");
-  MYASSERT (!tp_intset_is_member (method_error, TEST_F), "");
-
-  /* g gets unreferenced, but survives long enough for the call to complete
-   * successfully later, because the pending call holds a reference;
-   * however, unlike case D, here the pending call weakly references the
-   * proxy. This is never necessary, but is an interesting corner case that
-   * should be tested. */
-  g_message ("Starting call on g");
-  tp_cli_dbus_daemon_call_list_names (g, -1, listed_names, PTR (TEST_G),
-      destroy_user_data, (GObject *) g);
-  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_G), "");
-  g_message ("Unreferencing g");
-  copy_of_g = g;
-  g_object_add_weak_pointer (copy_of_g, &copy_of_g);
-  g_object_unref (g);
-  g = NULL;
-  MYASSERT (copy_of_g != NULL, "");
-  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_G), "");
-  MYASSERT (!tp_intset_is_member (method_ok, TEST_G), "");
-  MYASSERT (!tp_intset_is_member (method_error, TEST_G), "");
-
-  /* h gets unreferenced, *and* the call is cancelled (regression test for
-   * fd.o #14576) */
-  g_message ("Starting call on h");
-  pc = tp_cli_dbus_daemon_call_list_names (h, -1, listed_names, PTR (TEST_H),
-      destroy_user_data, NULL);
-  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_H), "");
-  g_message ("Unreferencing h");
-  copy_of_h = h;
-  g_object_add_weak_pointer (copy_of_h, &copy_of_h);
-  g_object_unref (h);
-  h = NULL;
-  MYASSERT (copy_of_h != NULL, "");
-  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_H), "");
-  MYASSERT (!tp_intset_is_member (method_ok, TEST_H), "");
-  MYASSERT (!tp_intset_is_member (method_error, TEST_H), "");
-  g_message ("Cancelling call on h");
-  tp_proxy_pending_call_cancel (pc);
-  MYASSERT (!tp_intset_is_member (method_ok, TEST_H), "");
-  MYASSERT (!tp_intset_is_member (method_error, TEST_H), "");
-
-  /* i gets its pending call cancelled because i_stub is
-   * destroyed, *and* the pending call holds the last reference to it,
-   * *and* there is a signal connection
-   * (used to reproduce fd.o #14750 - see case h in test-disconnection.c
-   * for the minimal regression test) */
-  i_stub = g_object_new (stub_object_get_type (), NULL);
-  tp_cli_dbus_daemon_connect_to_name_owner_changed (i, noc, PTR (TEST_I),
-      NULL, i_stub, NULL);
-  g_message ("Starting call on i");
-  tp_cli_dbus_daemon_call_list_names (i, -1, listed_names, PTR (TEST_I),
-      destroy_user_data, i_stub);
-  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_I), "");
-  tp_cli_dbus_daemon_connect_to_name_owner_changed (i, noc, PTR (TEST_I),
-      NULL, i_stub, NULL);
-  g_message ("Unreferencing i");
-  copy_of_i = i;
-  g_object_add_weak_pointer (copy_of_i, &copy_of_i);
-  g_object_unref (i);
-  i = NULL;
-  MYASSERT (copy_of_i != NULL, "");
-  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_I), "");
-  MYASSERT (!tp_intset_is_member (method_ok, TEST_I), "");
-  MYASSERT (!tp_intset_is_member (method_error, TEST_I), "");
-  g_object_unref (i_stub);
-  MYASSERT (!tp_intset_is_member (method_ok, TEST_I), "");
-  MYASSERT (!tp_intset_is_member (method_error, TEST_I), "");
-
-  /* j gets its pending call cancelled explicitly, and j_stub is
-   * destroyed in response (related to fd.o #14750) */
-  j_stub = g_object_new (stub_object_get_type (), NULL);
-  g_object_weak_ref (j_stub, j_stub_destroyed, PTR (TEST_J));
-  g_message ("Starting call on j");
-  pc = tp_cli_dbus_daemon_call_list_names (j, -1, listed_names, j_stub,
-      g_object_unref, j_stub);
-  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_J), "");
-  g_message ("Cancelling call on j");
-  tp_proxy_pending_call_cancel (pc);
-  MYASSERT (!tp_intset_is_member (method_ok, TEST_J), "");
-  MYASSERT (!tp_intset_is_member (method_error, TEST_J), "");
-
-  /* k gets its pending call cancelled explicitly because its weak object
-   * is destroyed, meaning there are simultaneously two reasons for it
-   * to become cancelled (equivalent to fd.o#14750, but for pending calls
-   * rather than signal connections) */
-  k_stub = g_object_new (stub_object_get_type (), NULL);
-  g_message ("Starting call on k");
-  g_object_weak_ref (k_stub, k_stub_destroyed, &pc);
-  pc = tp_cli_dbus_daemon_call_list_names (k, -1, listed_names, PTR (TEST_K),
-      destroy_user_data, k_stub);
-  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_K), "");
-  MYASSERT (!tp_intset_is_member (method_ok, TEST_K), "");
-  MYASSERT (!tp_intset_is_member (method_error, TEST_K), "");
-  g_object_unref (k_stub);
-  MYASSERT (!tp_intset_is_member (method_ok, TEST_K), "");
-  MYASSERT (!tp_intset_is_member (method_error, TEST_K), "");
-
-  /* z survives too; we assume that method calls succeed in order,
-   * so when z has had its reply, we can stop the main loop */
-  g_message ("Starting call on z");
-  tp_cli_dbus_daemon_call_list_names (z, -1, listed_names, PTR (TEST_Z),
-      destroy_user_data, (GObject *) a);
-  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_Z), "");
-  MYASSERT (!tp_intset_is_member (method_ok, TEST_Z), "");
-  MYASSERT (!tp_intset_is_member (method_error, TEST_Z), "");
-
-  g_message ("Running main loop");
-  g_main_loop_run (mainloop);
-  g_main_loop_unref (mainloop);
-
-  /* now that the calls have been delivered, d will finally have gone away */
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_D), "");
-  MYASSERT (tp_intset_is_member (method_ok, TEST_D), "");
-  MYASSERT (!tp_intset_is_member (method_error, TEST_D), "");
-  MYASSERT (copy_of_d == NULL, "");
-
-  /* ... and g too */
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_G), "");
-  MYASSERT (tp_intset_is_member (method_ok, TEST_G), "");
-  MYASSERT (!tp_intset_is_member (method_error, TEST_G), "");
-  MYASSERT (copy_of_g == NULL, "");
-
-  /* also, F will have been invalidated */
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_F), "");
-  MYASSERT (!tp_intset_is_member (method_ok, TEST_F), "");
-  MYASSERT (tp_intset_is_member (method_error, TEST_F), "");
-
-  /* Now that its call has been cancelled, h will have gone away. Likewise
-   * for i */
-  MYASSERT (copy_of_h == NULL, "");
-  MYASSERT (copy_of_i == NULL, "");
-
-  /* User data for all the cancelled calls has also gone away */
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_B), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_E), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_H), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_I), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_J), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_K), "");
-
-  /* the calls have been delivered to A, C and Z by now */
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_A), "");
-  MYASSERT (tp_intset_is_member (method_ok, TEST_A), "");
-  MYASSERT (!tp_intset_is_member (method_error, TEST_A), "");
-
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_C), "");
-  MYASSERT (tp_intset_is_member (method_ok, TEST_C), "");
-  MYASSERT (!tp_intset_is_member (method_error, TEST_C), "");
-
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_Z), "");
-  MYASSERT (tp_intset_is_member (method_ok, TEST_Z), "");
-  MYASSERT (!tp_intset_is_member (method_error, TEST_Z), "");
-
-  g_message ("Dereferencing remaining proxies");
-  g_object_unref (a);
-  g_object_unref (b);
-  g_object_unref (c);
-  MYASSERT (d == NULL, "");
-  g_object_unref (e);
-  g_object_unref (f);
-  MYASSERT (g == NULL, "");
-  MYASSERT (h == NULL, "");
-  MYASSERT (i == NULL, "");
-  g_object_unref (j);
-  g_object_unref (z);
-
-  /* we should already have checked each of these at least once, but just to
-   * make sure we have a systematic test that all user data is freed... */
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_A), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_B), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_C), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_D), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_E), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_F), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_G), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_H), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_I), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_J), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_K), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_Z), "");
-
-  tp_intset_destroy (freed_user_data);
-  tp_intset_destroy (method_ok);
-  tp_intset_destroy (method_error);
-
-  return 0;
-}
diff --git a/tests/dbus/test-dbus.c b/tests/dbus/test-dbus.c
deleted file mode 100644
index d8c6ce8..0000000
--- a/tests/dbus/test-dbus.c
+++ /dev/null
@@ -1,247 +0,0 @@
-#include <dbus/dbus-shared.h>
-#include <glib.h>
-#include <telepathy-glib/dbus.h>
-#include <telepathy-glib/debug.h>
-#include <telepathy-glib/util.h>
-
-#include "tests/lib/myassert.h"
-
-static GPtrArray *events;
-static TpDBusDaemon *bus;
-static GMainLoop *mainloop;
-static gchar *two = "2", *five = "5";
-static gboolean had_owners = FALSE;
-
-static void
-noc (TpDBusDaemon *obj,
-     const gchar *name,
-     const gchar *new_owner,
-     gpointer user_data)
-{
-  const gchar *tag = user_data;
-
-  g_message ("[%s] %s -> <%s>", tag, name, new_owner);
-
-  g_ptr_array_add (events, g_strdup_printf ("[%s] %s %d",
-        tag, name, new_owner[0]));
-
-  if (new_owner[0] != '\0')
-    had_owners = TRUE;
-
-  if (!tp_strdiff (name, "net.example"))
-    {
-      if (new_owner[0] == '\0')
-        {
-          if (had_owners)
-            {
-              g_main_loop_quit (mainloop);
-            }
-          else
-            {
-              guint ret;
-              GError *error = NULL;
-
-              MYASSERT (tp_cli_dbus_daemon_run_request_name (obj, -1,
-                    "com.example", 0, &ret, &error, NULL), "");
-              MYASSERT (ret == 1 && error == NULL, "");
-              MYASSERT (tp_cli_dbus_daemon_run_request_name (obj, -1,
-                    "org.example", 0, &ret, &error, NULL), "");
-              MYASSERT (ret == 1 && error == NULL, "");
-              MYASSERT (tp_cli_dbus_daemon_run_request_name (obj, -1,
-                    "net.example", 0, &ret, &error, NULL), "");
-              MYASSERT (ret == 1 && error == NULL, "");
-            }
-        }
-      else
-        {
-          guint ret;
-          GError *error = NULL;
-
-          MYASSERT (tp_dbus_daemon_cancel_name_owner_watch (obj,
-                "org.example", noc, five), "");
-          MYASSERT (tp_cli_dbus_daemon_run_release_name (obj, -1,
-                "org.example", &ret, &error, NULL), "");
-          MYASSERT (ret == 1 && error == NULL, "");
-          MYASSERT (tp_cli_dbus_daemon_run_release_name (obj, -1,
-                "net.example", &ret, &error, NULL), "");
-          MYASSERT (ret == 1 && error == NULL, "");
-        }
-    }
-}
-
-int
-main (int argc,
-      char **argv)
-{
-  guint i;
-
-  tp_debug_set_flags ("all");
-  mainloop = g_main_loop_new (NULL, FALSE);
-
-  events = g_ptr_array_new ();
-
-  g_type_init ();
-
-  MYASSERT (tp_dbus_check_valid_object_path ("/", NULL), "");
-  MYASSERT (tp_dbus_check_valid_object_path ("/a", NULL), "");
-  MYASSERT (tp_dbus_check_valid_object_path ("/foo", NULL), "");
-  MYASSERT (!tp_dbus_check_valid_object_path ("//", NULL), "");
-  MYASSERT (!tp_dbus_check_valid_object_path ("/a//b", NULL), "");
-  MYASSERT (tp_dbus_check_valid_object_path ("/a/b", NULL), "");
-  MYASSERT (!tp_dbus_check_valid_object_path ("/a/b/", NULL), "");
-  MYASSERT (!tp_dbus_check_valid_object_path ("a/b", NULL), "");
-  MYASSERT (!tp_dbus_check_valid_object_path ("/*a", NULL), "");
-
-#define TEST_LONG_BIT "excessively.long.name.longer.than._255.characters"
-#define TEST_LONG (TEST_LONG_BIT TEST_LONG_BIT TEST_LONG_BIT TEST_LONG_BIT \
-    TEST_LONG_BIT TEST_LONG_BIT TEST_LONG_BIT TEST_LONG_BIT)
-
-  MYASSERT (!tp_dbus_check_valid_member_name ("", NULL), "");
-  MYASSERT (!tp_dbus_check_valid_member_name ("123abc", NULL), "");
-  MYASSERT (!tp_dbus_check_valid_member_name ("a.b", NULL), "");
-  MYASSERT (!tp_dbus_check_valid_member_name ("a*b", NULL), "");
-  MYASSERT (tp_dbus_check_valid_member_name ("example", NULL), "");
-  MYASSERT (tp_dbus_check_valid_member_name ("_1", NULL), "");
-
-  MYASSERT (!tp_dbus_check_valid_interface_name ("", NULL), "");
-  MYASSERT (!tp_dbus_check_valid_interface_name (TEST_LONG, NULL), "");
-  MYASSERT (!tp_dbus_check_valid_interface_name ("hasnodot", NULL), "");
-  MYASSERT (!tp_dbus_check_valid_interface_name ("123abc.example", NULL), "");
-  MYASSERT (!tp_dbus_check_valid_interface_name ("com.1", NULL), "");
-  MYASSERT (!tp_dbus_check_valid_interface_name ("com.e*ample", NULL), "");
-  MYASSERT (!tp_dbus_check_valid_interface_name ("com..example", NULL), "");
-  MYASSERT (!tp_dbus_check_valid_interface_name (".com.example", NULL), "");
-  MYASSERT (!tp_dbus_check_valid_interface_name ("com.example.", NULL), "");
-  MYASSERT (tp_dbus_check_valid_interface_name ("com.example", NULL), "");
-  MYASSERT (tp_dbus_check_valid_interface_name ("com._1", NULL), "");
-
-  MYASSERT (tp_dbus_check_valid_bus_name (":1.1", TP_DBUS_NAME_TYPE_ANY,
-        NULL), "");
-  MYASSERT (tp_dbus_check_valid_bus_name ("com.example", TP_DBUS_NAME_TYPE_ANY,
-        NULL), "");
-  MYASSERT (tp_dbus_check_valid_bus_name (DBUS_SERVICE_DBUS,
-        TP_DBUS_NAME_TYPE_ANY, NULL), "");
-
-  MYASSERT (tp_dbus_check_valid_bus_name (":1.1",
-        TP_DBUS_NAME_TYPE_NOT_BUS_DAEMON, NULL), "");
-  MYASSERT (tp_dbus_check_valid_bus_name ("com.example",
-        TP_DBUS_NAME_TYPE_NOT_BUS_DAEMON, NULL), "");
-  MYASSERT (!tp_dbus_check_valid_bus_name (DBUS_SERVICE_DBUS,
-        TP_DBUS_NAME_TYPE_NOT_BUS_DAEMON, NULL), "");
-
-  MYASSERT (!tp_dbus_check_valid_bus_name (":1.1",
-        TP_DBUS_NAME_TYPE_BUS_DAEMON, NULL), "");
-  MYASSERT (!tp_dbus_check_valid_bus_name ("com.example",
-        TP_DBUS_NAME_TYPE_BUS_DAEMON, NULL), "");
-  MYASSERT (tp_dbus_check_valid_bus_name (DBUS_SERVICE_DBUS,
-        TP_DBUS_NAME_TYPE_BUS_DAEMON, NULL), "");
-
-  MYASSERT (!tp_dbus_check_valid_bus_name (":1.1",
-        TP_DBUS_NAME_TYPE_WELL_KNOWN, NULL), "");
-  MYASSERT (tp_dbus_check_valid_bus_name ("com.example",
-        TP_DBUS_NAME_TYPE_WELL_KNOWN, NULL), "");
-  MYASSERT (!tp_dbus_check_valid_bus_name (DBUS_SERVICE_DBUS,
-        TP_DBUS_NAME_TYPE_WELL_KNOWN, NULL), "");
-
-  MYASSERT (tp_dbus_check_valid_bus_name (":1.1",
-        TP_DBUS_NAME_TYPE_UNIQUE, NULL), "");
-  MYASSERT (!tp_dbus_check_valid_bus_name ("com.example",
-        TP_DBUS_NAME_TYPE_UNIQUE, NULL), "");
-  MYASSERT (!tp_dbus_check_valid_bus_name (DBUS_SERVICE_DBUS,
-        TP_DBUS_NAME_TYPE_UNIQUE, NULL), "");
-
-  MYASSERT (tp_dbus_check_valid_bus_name ("com._1",
-        TP_DBUS_NAME_TYPE_ANY, NULL), "");
-  MYASSERT (!tp_dbus_check_valid_bus_name ("",
-        TP_DBUS_NAME_TYPE_ANY, NULL), "");
-  MYASSERT (!tp_dbus_check_valid_bus_name (TEST_LONG,
-        TP_DBUS_NAME_TYPE_ANY, NULL), "");
-  MYASSERT (!tp_dbus_check_valid_bus_name ("hasnodot",
-        TP_DBUS_NAME_TYPE_ANY, NULL), "");
-  MYASSERT (!tp_dbus_check_valid_bus_name ("123abc.example",
-        TP_DBUS_NAME_TYPE_ANY, NULL), "");
-  MYASSERT (!tp_dbus_check_valid_bus_name ("com.1",
-        TP_DBUS_NAME_TYPE_ANY, NULL), "");
-  MYASSERT (!tp_dbus_check_valid_bus_name ("com.e*ample",
-        TP_DBUS_NAME_TYPE_ANY, NULL), "");
-  MYASSERT (!tp_dbus_check_valid_bus_name ("com..example",
-        TP_DBUS_NAME_TYPE_ANY, NULL), "");
-  MYASSERT (!tp_dbus_check_valid_bus_name (".com.example",
-        TP_DBUS_NAME_TYPE_ANY, NULL), "");
-  MYASSERT (!tp_dbus_check_valid_bus_name ("com.example.",
-        TP_DBUS_NAME_TYPE_ANY, NULL), "");
-  MYASSERT (!tp_dbus_check_valid_bus_name (":1.1.",
-        TP_DBUS_NAME_TYPE_ANY, NULL), "");
-
-  bus = tp_dbus_daemon_new (tp_get_bus ());
-
-  /* Regression test for properties */
-    {
-      gchar *bus_name;
-      gchar *object_path;
-      DBusGConnection *dbus_conn;
-
-      g_object_get (bus,
-          "dbus-connection", &dbus_conn,
-          "bus-name", &bus_name,
-          "object-path", &object_path,
-          NULL);
-
-      MYASSERT (object_path != NULL, "");
-      MYASSERT (object_path[0] == '/', "%s", object_path);
-      MYASSERT (bus_name != NULL, "");
-      MYASSERT (!tp_strdiff (bus_name, "org.freedesktop.DBus"),
-            "%s", bus_name);
-      MYASSERT (dbus_conn != NULL, "");
-      MYASSERT (dbus_conn == tp_get_bus (), "%p != %p", dbus_conn,
-          tp_get_bus ());
-
-      g_free (bus_name);
-      g_free (object_path);
-      dbus_g_connection_unref (dbus_conn);
-    }
-
-  tp_dbus_daemon_watch_name_owner (bus, "com.example", noc, "1", NULL);
-  tp_dbus_daemon_watch_name_owner (bus, "com.example", noc, two, NULL);
-  tp_dbus_daemon_watch_name_owner (bus, "com.example", noc, "3", NULL);
-  tp_dbus_daemon_cancel_name_owner_watch (bus, "com.example", noc, two);
-  tp_dbus_daemon_watch_name_owner (bus, "net.example", noc, "4", NULL);
-  tp_dbus_daemon_watch_name_owner (bus, "org.example", noc, five, NULL);
-
-  g_main_loop_run (mainloop);
-
-  MYASSERT (events->len == 9, "");
-
-  /* 58 == ':' - i.e. the beginning of a unique name */
-  MYASSERT (!tp_strdiff (g_ptr_array_index (events, 0),
-        "[1] com.example 0"), "");
-  MYASSERT (!tp_strdiff (g_ptr_array_index (events, 1),
-        "[3] com.example 0"), "");
-  MYASSERT (!tp_strdiff (g_ptr_array_index (events, 2),
-        "[4] net.example 0"), "");
-  MYASSERT (!tp_strdiff (g_ptr_array_index (events, 3),
-        "[5] org.example 0"), "");
-
-  MYASSERT (!tp_strdiff (g_ptr_array_index (events, 4),
-        "[1] com.example 58"), "");
-  MYASSERT (!tp_strdiff (g_ptr_array_index (events, 5),
-        "[3] com.example 58"), "");
-  MYASSERT (!tp_strdiff (g_ptr_array_index (events, 6),
-        "[5] org.example 58"), "");
-  MYASSERT (!tp_strdiff (g_ptr_array_index (events, 7),
-        "[4] net.example 58"), "");
-  MYASSERT (!tp_strdiff (g_ptr_array_index (events, 8),
-        "[4] net.example 0"), "");
-
-  /* keep valgrind happy, at least in the successful case */
-  for (i = 0; i < events->len; i++)
-    {
-      g_free (events->pdata[i]);
-    }
-
-  g_ptr_array_free (events, TRUE);
-  g_main_loop_unref (mainloop);
-  mainloop = NULL;
-
-  return 0;
-}
diff --git a/tests/dbus/test-disconnection.c b/tests/dbus/test-disconnection.c
deleted file mode 100644
index 815f6aa..0000000
--- a/tests/dbus/test-disconnection.c
+++ /dev/null
@@ -1,376 +0,0 @@
-#include <telepathy-glib/dbus.h>
-#include <telepathy-glib/debug.h>
-#include <telepathy-glib/errors.h>
-#include <telepathy-glib/interfaces.h>
-#include <telepathy-glib/intset.h>
-#include <telepathy-glib/proxy-subclass.h>    /* for _invalidated etc. */
-#include <telepathy-glib/util.h>
-
-#include "tests/lib/myassert.h"
-#include "tests/lib/stub-object.h"
-#include "tests/lib/util.h"
-
-/* just for convenience, since it's used a lot */
-#define PTR(ui) GUINT_TO_POINTER(ui)
-
-/* state tracking */
-static GMainLoop *mainloop;
-static TpDBusDaemon *a;
-static TpDBusDaemon *b;
-static TpDBusDaemon *c;
-static TpDBusDaemon *d;
-static TpDBusDaemon *e;
-static TpDBusDaemon *f;
-static TpDBusDaemon *g;
-static TpDBusDaemon *h;
-static TpDBusDaemon *z;
-static TpIntSet *caught_signal;
-static TpIntSet *freed_user_data;
-
-enum {
-    TEST_A,
-    TEST_B,
-    TEST_C,
-    TEST_D,
-    TEST_E,
-    TEST_F,
-    TEST_G,
-    TEST_H,
-    TEST_Z = 25,
-    N_DAEMONS
-};
-
-static void
-h_stub_destroyed (gpointer data,
-                  GObject *stub)
-{
-  TpProxySignalConnection **p = data;
-
-  tp_proxy_signal_connection_disconnect (*p);
-}
-
-static void
-destroy_user_data (gpointer user_data)
-{
-  guint which = GPOINTER_TO_UINT (user_data);
-  g_message ("User data %c destroyed", 'A' + which);
-  MYASSERT (!tp_intset_is_member (freed_user_data, which), "");
-  tp_intset_add (freed_user_data, which);
-}
-
-static void
-requested_name (TpDBusDaemon *proxy,
-                guint result,
-                const GError *error,
-                gpointer user_data,
-                GObject *weak_object)
-{
-  g_message ("RequestName raised %s",
-      (error == NULL ? "no error" : error->message));
-  /* we're on a private bus, so certainly nobody else should own this name */
-  test_assert_no_error (error);
-  MYASSERT (result == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER, ": %u", result);
-}
-
-static void
-prop_changed (TpProxy *proxy,
-              const GPtrArray *properties,
-              gpointer user_data,
-              GObject *weak_object)
-{
-  g_error ("prop_changed called - a signal connection which should have "
-      "failed has succeeded. Args: proxy=%p user_data=%p", proxy, user_data);
-}
-
-static void
-dummy_noc (TpDBusDaemon *proxy,
-           const gchar *name,
-           const gchar *old,
-           const gchar *new,
-           gpointer user_data,
-           GObject *weak_object)
-{
-  g_error ("dummy_noc called - a signal connection which should have "
-      "failed has succeeded. Args: proxy=%p user_data=%p", proxy, user_data);
-}
-
-static void
-noc (TpDBusDaemon *proxy,
-     const gchar *name,
-     const gchar *old,
-     const gchar *new,
-     gpointer user_data,
-     GObject *weak_object)
-{
-  guint which = GPOINTER_TO_UINT (user_data);
-  TpDBusDaemon *want_proxy = NULL;
-  GObject *want_object = NULL;
-
-  g_message ("Caught signal (%s: %s -> %s) with proxy #%d '%c' according to "
-      "user_data", name, old, new, which, 'a' + which);
-  g_message ("Proxy is %p, weak object is %p", proxy,
-      weak_object);
-  tp_intset_add (caught_signal, which);
-
-  switch (which)
-    {
-    case TEST_A:
-      want_proxy = a;
-      want_object = (GObject *) z;
-      break;
-    case TEST_Z:
-      want_proxy = z;
-      want_object = (GObject *) a;
-      break;
-    default:
-      g_error ("%c (%p) got the signal, which shouldn't have happened",
-          'a' + which, proxy);
-    }
-
-  g_message ("Expecting proxy %p, weak object %p", want_proxy, want_object);
-
-  MYASSERT (proxy == want_proxy, ": %p != %p", proxy, want_proxy);
-  MYASSERT (weak_object == want_object, ": %p != %p", weak_object,
-      want_object);
-
-  if (tp_intset_is_member (caught_signal, TEST_A) &&
-      tp_intset_is_member (caught_signal, TEST_Z))
-    {
-      /* we've had all the signals we're going to */
-      g_main_loop_quit (mainloop);
-    }
-}
-
-static void
-set_freed (gpointer user_data)
-{
-  gboolean *boolptr = user_data;
-
-  MYASSERT (*boolptr == FALSE, "");
-  *boolptr = TRUE;
-}
-
-int
-main (int argc,
-      char **argv)
-{
-  GObject *stub;
-  GError *error_out = NULL;
-  GError err = { TP_ERRORS, TP_ERROR_INVALID_ARGUMENT, "Because I said so" };
-  TpProxySignalConnection *sc;
-  gpointer tmp_obj;
-  gboolean freed = FALSE;
-
-  g_type_init ();
-  tp_debug_set_flags ("all");
-
-  freed_user_data = tp_intset_sized_new (N_DAEMONS);
-  caught_signal = tp_intset_sized_new (N_DAEMONS);
-
-  mainloop = g_main_loop_new (NULL, FALSE);
-
-  /* We use TpDBusDaemon because it's a convenient concrete subclass of
-   * TpProxy. */
-  g_message ("Creating proxies");
-  a = tp_dbus_daemon_new (tp_get_bus ());
-  g_message ("a=%p", a);
-  b = tp_dbus_daemon_new (tp_get_bus ());
-  g_message ("b=%p", b);
-  c = tp_dbus_daemon_new (tp_get_bus ());
-  g_message ("c=%p", c);
-  d = tp_dbus_daemon_new (tp_get_bus ());
-  g_message ("d=%p", d);
-  e = tp_dbus_daemon_new (tp_get_bus ());
-  g_message ("e=%p", e);
-  f = tp_dbus_daemon_new (tp_get_bus ());
-  g_message ("f=%p", f);
-  g = tp_dbus_daemon_new (tp_get_bus ());
-  g_message ("g=%p", g);
-  h = tp_dbus_daemon_new (tp_get_bus ());
-  g_message ("h=%p", h);
-  z = tp_dbus_daemon_new (tp_get_bus ());
-  g_message ("z=%p", z);
-
-  /* a survives */
-  g_message ("Connecting signal to a");
-  tp_cli_dbus_daemon_connect_to_name_owner_changed (a, noc, PTR (TEST_A),
-      destroy_user_data, (GObject *) z, &error_out);
-  test_assert_no_error (error_out);
-
-  /* assert that connecting to a signal on an interface we don't have fails */
-  freed = FALSE;
-  tp_cli_properties_interface_connect_to_properties_changed (a, prop_changed,
-      &freed, set_freed, NULL, &error_out);
-  MYASSERT (freed, "");
-  MYASSERT (error_out != NULL, "");
-  MYASSERT (error_out->code == TP_DBUS_ERROR_NO_INTERFACE, "");
-  g_error_free (error_out);
-  error_out = NULL;
-
-  /* b gets its signal connection cancelled because stub is
-   * destroyed */
-  stub = g_object_new (stub_object_get_type (), NULL);
-  g_message ("Connecting signal to b");
-  tp_cli_dbus_daemon_connect_to_name_owner_changed (b, noc, PTR (TEST_B),
-      destroy_user_data, stub, &error_out);
-  test_assert_no_error (error_out);
-  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_B), "");
-  g_object_unref (stub);
-
-  /* c gets its signal connection cancelled because it's explicitly
-   * invalidated */
-  g_message ("Connecting signal to c");
-  tp_cli_dbus_daemon_connect_to_name_owner_changed (c, noc, PTR (TEST_C),
-      destroy_user_data, NULL, &error_out);
-  test_assert_no_error (error_out);
-  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_C), "");
-  g_message ("Forcibly invalidating c");
-  tp_proxy_invalidate ((TpProxy *) c, &err);
-  /* assert that connecting to a signal on an invalid proxy fails */
-  freed = FALSE;
-  tp_cli_dbus_daemon_connect_to_name_owner_changed (c, dummy_noc, &freed,
-      set_freed, NULL, &error_out);
-  MYASSERT (freed, "");
-  MYASSERT (error_out != NULL, "");
-  g_message ("%d: %d: %s", error_out->domain, error_out->code,
-      error_out->message);
-  MYASSERT (error_out->code == err.code, "%d != %d", error_out->code,
-      err.code);
-  g_error_free (error_out);
-  error_out = NULL;
-
-  /* d gets its signal connection cancelled because it's
-   * implicitly invalidated by being destroyed */
-  g_message ("Connecting signal to d");
-  tp_cli_dbus_daemon_connect_to_name_owner_changed (d, noc, PTR (TEST_D),
-      destroy_user_data, NULL, &error_out);
-  test_assert_no_error (error_out);
-  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_D), "");
-  g_message ("Destroying d");
-  tmp_obj = d;
-  g_object_add_weak_pointer (tmp_obj, &tmp_obj);
-  g_object_unref (d);
-  MYASSERT (tmp_obj == NULL, "");
-  d = NULL;
-
-  /* e gets its signal connection cancelled explicitly */
-  g_message ("Connecting signal to e");
-  sc = tp_cli_dbus_daemon_connect_to_name_owner_changed (e, noc, PTR (TEST_E),
-      destroy_user_data, NULL, &error_out);
-  test_assert_no_error (error_out);
-  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_E), "");
-  g_message ("Disconnecting signal from e");
-  tp_proxy_signal_connection_disconnect (sc);
-
-  /* f gets its signal connection cancelled because it's implicitly
-   * invalidated by its DBusGProxy being destroyed.
-   *
-   * Note that this test case exploits implementation details of dbus-glib.
-   * If it stops working after a dbus-glib upgrade, that's probably why. */
-  g_message ("Connecting signal to f");
-  tp_cli_dbus_daemon_connect_to_name_owner_changed (f, noc, PTR (TEST_F),
-      destroy_user_data, NULL, &error_out);
-  test_assert_no_error (error_out);
-  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_F), "");
-  g_message ("Forcibly disposing f's DBusGProxy to simulate name owner loss");
-  tmp_obj = tp_proxy_borrow_interface_by_id ((TpProxy *) f,
-      TP_IFACE_QUARK_DBUS_DAEMON, NULL);
-  MYASSERT (tmp_obj != NULL, "");
-  g_object_run_dispose (tmp_obj);
-  /* assert that connecting to a signal on an invalid proxy fails */
-  freed = FALSE;
-  tp_cli_dbus_daemon_connect_to_name_owner_changed (f, dummy_noc, &freed,
-      set_freed, NULL, &error_out);
-  MYASSERT (freed, "");
-  MYASSERT (error_out != NULL, "");
-  MYASSERT (error_out->code == DBUS_GERROR_NAME_HAS_NO_OWNER, "");
-  g_error_free (error_out);
-  error_out = NULL;
-
-  /* g gets its signal connection cancelled because it's
-   * implicitly invalidated by being destroyed; unlike d, the signal
-   * connection weakly references the proxy. This is never necessary, but is
-   * an interesting corner case that should be tested. */
-  g_message ("Connecting signal to g");
-  tp_cli_dbus_daemon_connect_to_name_owner_changed (g, noc, PTR (TEST_G),
-      destroy_user_data, (GObject *) g, &error_out);
-  test_assert_no_error (error_out);
-  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_G), "");
-  g_message ("Destroying g");
-  tmp_obj = g;
-  g_object_add_weak_pointer (tmp_obj, &tmp_obj);
-  g_object_unref (g);
-  MYASSERT (tmp_obj == NULL, "");
-  g = NULL;
-
-  /* h gets its signal connection cancelled because its weak object is
-   * destroyed, meaning there are simultaneously two reasons for it to become
-   * cancelled (fd.o#14750) */
-  stub = g_object_new (stub_object_get_type (), NULL);
-  g_object_weak_ref (stub, h_stub_destroyed, &sc);
-  g_message ("Connecting signal to h");
-  sc = tp_cli_dbus_daemon_connect_to_name_owner_changed (h, noc, PTR (TEST_H),
-      destroy_user_data, stub, &error_out);
-  test_assert_no_error (error_out);
-  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_H), "");
-  g_object_unref (stub);
-
-  /* z survives; we assume that the signals are delivered in either
-   * forward or reverse order, so if both a and z have had their signal, we
-   * can stop the main loop */
-  g_message ("Connecting signal to z");
-  tp_cli_dbus_daemon_connect_to_name_owner_changed (z, noc, PTR (TEST_Z),
-      destroy_user_data, (GObject *) a, &error_out);
-  test_assert_no_error (error_out);
-
-  /* make sure a NameOwnerChanged signal occurs */
-  g_message ("Requesting name");
-  tp_cli_dbus_daemon_call_request_name (a, -1, "com.example.NameTest",
-      0, requested_name, NULL, NULL, NULL);
-
-  g_message ("Running main loop");
-  g_main_loop_run (mainloop);
-  g_main_loop_unref (mainloop);
-
-  /* Now that the main loop has run, cancelled signal connections have been
-   * freed */
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_B), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_C), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_D), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_E), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_F), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_G), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_H), "");
-
-  /* both A and Z are still listening for signals, so their user data is
-   * still held */
-  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_A), "");
-  MYASSERT (!tp_intset_is_member (freed_user_data, TEST_Z), "");
-
-  g_message ("Dereferencing remaining proxies");
-  g_object_unref (a);
-  g_object_unref (b);
-  g_object_unref (c);
-  MYASSERT (d == NULL, "");
-  g_object_unref (e);
-  g_object_unref (f);
-  MYASSERT (g == NULL, "");
-  g_object_unref (z);
-
-  /* we should already have checked each of these at least once, but just to
-   * make sure we have a systematic test that all user data is freed... */
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_A), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_B), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_C), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_D), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_E), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_F), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_G), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_H), "");
-  MYASSERT (tp_intset_is_member (freed_user_data, TEST_Z), "");
-
-  tp_intset_destroy (freed_user_data);
-  tp_intset_destroy (caught_signal);
-
-  return 0;
-}
diff --git a/tests/dbus/test-example-no-protocols.c b/tests/dbus/test-example-no-protocols.c
deleted file mode 100644
index 201fe64..0000000
--- a/tests/dbus/test-example-no-protocols.c
+++ /dev/null
@@ -1,96 +0,0 @@
-#include <glib-object.h>
-#include <telepathy-glib/connection-manager.h>
-#include <telepathy-glib/debug.h>
-#include <telepathy-glib/defs.h>
-#include <telepathy-glib/errors.h>
-
-static void
-prepare (void)
-{
-  GError *error = NULL;
-  const gchar *abs_top_builddir = g_getenv ("abs_top_builddir");
-  gchar *command[] = {
-      g_strdup_printf ("%s/%s",
-          abs_top_builddir,
-          "examples/cm/no-protocols/telepathy-example-no-protocols"),
-      NULL
-  };
-
-  g_assert (abs_top_builddir != NULL);
-
-  if (!g_spawn_async (NULL, command, NULL, 0, NULL, NULL, NULL, &error))
-    {
-      g_error ("g_spawn_async: %s", error->message);
-    }
-
-  g_free (command[0]);
-}
-
-static void
-connection_manager_got_info (TpConnectionManager *cm,
-                             guint source,
-                             GMainLoop *mainloop)
-{
-  GHashTable *empty = g_hash_table_new (NULL, NULL);
-  gchar *bus_name = NULL;
-  gchar *object_path = NULL;
-  GError *error = NULL;
-
-  g_message ("Emitted got-info (source=%d)", source);
-
-  if (source < TP_CM_INFO_SOURCE_LIVE)
-    return;
-
-  tp_cli_connection_manager_run_request_connection (cm, -1,
-      "jabber", empty, &bus_name, &object_path, &error, NULL);
-
-  g_assert (error != NULL);
-  g_assert (error->domain == TP_ERRORS);
-  g_assert (error->code == TP_ERROR_NOT_IMPLEMENTED);
-
-  g_error_free (error);
-
-  g_main_loop_quit (mainloop);
-
-  g_hash_table_destroy (empty);
-}
-
-static gboolean
-time_out (gpointer mainloop)
-{
-  g_error ("Timed out");
-  g_assert_not_reached ();
-  return FALSE;
-}
-
-int
-main (int argc,
-      char **argv)
-{
-  GMainLoop *mainloop;
-  TpConnectionManager *cm;
-
-  prepare ();
-
-  g_type_init ();
-
-  tp_debug_set_flags ("all");
-
-  mainloop = g_main_loop_new (NULL, FALSE);
-
-  cm = tp_connection_manager_new (tp_dbus_daemon_new (tp_get_bus ()),
-      "example_no_protocols", NULL, NULL);
-  g_assert (cm != NULL);
-
-  g_signal_connect (cm, "got-info",
-      G_CALLBACK (connection_manager_got_info), mainloop);
-
-  g_timeout_add (5000, time_out, mainloop);
-
-  g_main_loop_run (mainloop);
-
-  g_object_unref (cm);
-  g_main_loop_unref (mainloop);
-
-  return 0;
-}
diff --git a/tests/heap.c b/tests/heap.c
new file mode 100644
index 0000000..2bf6e7d
--- /dev/null
+++ b/tests/heap.c
@@ -0,0 +1,39 @@
+#include <telepathy-glib/intset.h>
+#include <telepathy-glib/heap.h>
+
+#include <stdlib.h>
+#include <time.h>
+#include <stdio.h>
+
+static gint comparator_fn (gconstpointer a, gconstpointer b)
+{
+    return (a < b) ? -1 : (a == b) ? 0 : 1;
+}
+
+int
+main (int argc,
+      char **argv)
+{
+  TpHeap *heap = tp_heap_new (comparator_fn, NULL);
+  guint prev = 0;
+  guint i;
+
+  srand (time (NULL));
+
+  for (i=0; i<10000; i++)
+    {
+      tp_heap_add (heap, GUINT_TO_POINTER (rand ()));
+    }
+
+  while (tp_heap_size (heap))
+    {
+      guint elem = GPOINTER_TO_INT (tp_heap_peek_first (heap));
+      g_assert (elem == GPOINTER_TO_UINT (tp_heap_extract_first (heap)));
+      g_assert (prev <= elem);
+      prev = elem;
+    }
+
+  tp_heap_destroy (heap);
+
+  return 0;
+}
diff --git a/tests/internal-debug.c b/tests/internal-debug.c
new file mode 100644
index 0000000..b852da7
--- /dev/null
+++ b/tests/internal-debug.c
@@ -0,0 +1,79 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <glib.h>
+
+#include <telepathy-glib/debug.h>
+
+#undef DEBUG_FLAG
+#define DEBUG_FLAG TP_DEBUG_IM
+#include "telepathy-glib/debug-internal.h"
+
+static void
+test_debugging (void)
+{
+#ifndef DEBUG
+#error internal-debug.h should always define DEBUG
+#endif
+
+#ifndef DEBUGGING
+#error internal-debug.h should always define DEBUGGING
+#endif
+
+#ifdef ENABLE_DEBUG
+  g_assert (DEBUGGING == 1);
+#else
+  g_assert (DEBUGGING == 0);
+#endif
+}
+
+#undef DEBUG_FLAG
+#define DEBUG_FLAG TP_DEBUG_CONNECTION
+#include "telepathy-glib/debug-internal.h"
+
+static void
+test_not_debugging (void)
+{
+#ifndef DEBUG
+#error internal-debug.h should always define DEBUG
+#endif
+
+#ifndef DEBUGGING
+#error internal-debug.h should always define DEBUGGING
+#endif
+
+  g_assert (DEBUGGING == 0);
+}
+
+#undef DEBUG_FLAG
+#define DEBUG_FLAG TP_DEBUG_IM
+#include "telepathy-glib/debug-internal.h"
+
+static void
+test_debugging_again (void)
+{
+#ifndef DEBUG
+#error internal-debug.h should always define DEBUG
+#endif
+
+#ifndef DEBUGGING
+#error internal-debug.h should always define DEBUGGING
+#endif
+
+#ifdef ENABLE_DEBUG
+  g_assert (DEBUGGING == 1);
+#else
+  g_assert (DEBUGGING == 0);
+#endif
+}
+
+int
+main (int argc, char **argv)
+{
+  /* We enable debugging for IM, but not for the connection. */
+  tp_debug_set_flags ("im");
+  test_debugging ();
+  test_not_debugging ();
+  test_debugging_again ();
+  return 0;
+}
diff --git a/tests/intset.c b/tests/intset.c
new file mode 100644
index 0000000..eca52bf
--- /dev/null
+++ b/tests/intset.c
@@ -0,0 +1,138 @@
+#include <glib.h>
+#include <telepathy-glib/intset.h>
+
+int main (int argc, char **argv)
+{
+  TpIntSet *set1 = tp_intset_new ();
+  TpIntSet *a, *b;
+  TpIntSet *ab_union, *ab_expected_union;
+  TpIntSet *ab_inter, *ab_expected_inter;
+  TpIntSet *a_diff_b, *a_expected_diff_b;
+  TpIntSet *b_diff_a, *b_expected_diff_a;
+  TpIntSet *ab_symmdiff, *ab_expected_symmdiff;
+
+  tp_intset_add (set1, 0);
+
+  tp_intset_add (set1, 2);
+  tp_intset_add (set1, 3);
+  tp_intset_add (set1, 5);
+  tp_intset_add (set1, 8);
+
+  tp_intset_add (set1, 1024);
+  tp_intset_add (set1, 32);
+
+  g_assert (tp_intset_size (set1) == 7);
+
+  g_assert (tp_intset_is_member (set1, 2));
+  g_assert (tp_intset_is_member (set1, 5));
+  g_assert (tp_intset_is_member (set1, 1024));
+  g_assert (!tp_intset_is_member (set1, 1023));
+  g_assert (!tp_intset_is_member (set1, 1025));
+  g_assert (tp_intset_is_member (set1, 0));
+  g_assert (tp_intset_is_member (set1, 32));
+  g_assert (!tp_intset_is_member (set1, 31));
+  g_assert (!tp_intset_is_member (set1, 33));
+
+  tp_intset_remove (set1, 8);
+  tp_intset_remove (set1, 1024);
+  g_assert (tp_intset_size (set1) == 5);
+
+  tp_intset_destroy (set1);
+
+#define NUM_A 11
+#define NUM_B 823
+#define NUM_C 367
+#define NUM_D 4177
+#define NUM_E 109
+#define NUM_F 1861
+
+  a = tp_intset_new ();
+  tp_intset_add (a, NUM_A);
+  tp_intset_add (a, NUM_B);
+  tp_intset_add (a, NUM_C);
+  tp_intset_add (a, NUM_D);
+
+  g_assert (tp_intset_is_equal (a, a));
+
+  b = tp_intset_new ();
+  tp_intset_add (b, NUM_C);
+  tp_intset_add (b, NUM_D);
+  tp_intset_add (b, NUM_E);
+  tp_intset_add (b, NUM_F);
+
+  g_assert (tp_intset_is_equal (b, b));
+  g_assert (!tp_intset_is_equal (a, b));
+
+  ab_expected_union = tp_intset_new ();
+  tp_intset_add (ab_expected_union, NUM_A);
+  tp_intset_add (ab_expected_union, NUM_B);
+  tp_intset_add (ab_expected_union, NUM_C);
+  tp_intset_add (ab_expected_union, NUM_D);
+  tp_intset_add (ab_expected_union, NUM_E);
+  tp_intset_add (ab_expected_union, NUM_F);
+
+  ab_union = tp_intset_union (a, b);
+  g_assert (tp_intset_is_equal (ab_union, ab_expected_union));
+  tp_intset_destroy (ab_union);
+  tp_intset_destroy (ab_expected_union);
+
+  ab_expected_inter = tp_intset_new ();
+  tp_intset_add (ab_expected_inter, NUM_C);
+  tp_intset_add (ab_expected_inter, NUM_D);
+
+  ab_inter = tp_intset_intersection (a, b);
+  g_assert (tp_intset_is_equal (ab_inter, ab_expected_inter));
+  tp_intset_destroy (ab_inter);
+  tp_intset_destroy (ab_expected_inter);
+
+  a_expected_diff_b = tp_intset_new ();
+  tp_intset_add (a_expected_diff_b, NUM_A);
+  tp_intset_add (a_expected_diff_b, NUM_B);
+
+  a_diff_b = tp_intset_difference (a, b);
+  g_assert (tp_intset_is_equal (a_diff_b, a_expected_diff_b));
+  tp_intset_destroy (a_diff_b);
+  tp_intset_destroy (a_expected_diff_b);
+
+  b_expected_diff_a = tp_intset_new ();
+  tp_intset_add (b_expected_diff_a, NUM_E);
+  tp_intset_add (b_expected_diff_a, NUM_F);
+
+  b_diff_a = tp_intset_difference (b, a);
+  g_assert (tp_intset_is_equal (b_diff_a, b_expected_diff_a));
+  tp_intset_destroy (b_diff_a);
+  tp_intset_destroy (b_expected_diff_a);
+
+  ab_expected_symmdiff = tp_intset_new ();
+  tp_intset_add (ab_expected_symmdiff, NUM_A);
+  tp_intset_add (ab_expected_symmdiff, NUM_B);
+  tp_intset_add (ab_expected_symmdiff, NUM_E);
+  tp_intset_add (ab_expected_symmdiff, NUM_F);
+
+  ab_symmdiff = tp_intset_symmetric_difference (a, b);
+  g_assert (tp_intset_is_equal (ab_symmdiff, ab_expected_symmdiff));
+  tp_intset_destroy (ab_symmdiff);
+  tp_intset_destroy (ab_expected_symmdiff);
+
+  {
+    GArray *arr;
+    TpIntSet *tmp;
+
+    arr = tp_intset_to_array (a);
+    tmp = tp_intset_from_array (arr);
+    g_assert (tp_intset_is_equal (a, tmp));
+    g_array_free (arr, TRUE);
+    tp_intset_destroy (tmp);
+
+    arr = tp_intset_to_array (b);
+    tmp = tp_intset_from_array (arr);
+    g_assert (tp_intset_is_equal (b, tmp));
+    g_array_free (arr, TRUE);
+    tp_intset_destroy (tmp);
+  }
+
+  tp_intset_destroy (a);
+  tp_intset_destroy (b);
+
+  return 0;
+}
diff --git a/tests/test-availability-cmp.c b/tests/test-availability-cmp.c
deleted file mode 100644
index 56ce828..0000000
--- a/tests/test-availability-cmp.c
+++ /dev/null
@@ -1,16 +0,0 @@
-#include <glib.h>
-#include <telepathy-glib/connection.h>
-
-int main (int argc, char **argv)
-{
-  g_assert (tp_connection_presence_type_cmp_availability (
-    TP_CONNECTION_PRESENCE_TYPE_AWAY, TP_CONNECTION_PRESENCE_TYPE_UNSET) == 1);
-
-  g_assert (tp_connection_presence_type_cmp_availability (
-    TP_CONNECTION_PRESENCE_TYPE_BUSY, TP_CONNECTION_PRESENCE_TYPE_AVAILABLE) == -1);
-
-  g_assert (tp_connection_presence_type_cmp_availability (
-    TP_CONNECTION_PRESENCE_TYPE_UNKNOWN, 100) == 0);
-
-  return 0;
-}
diff --git a/tests/test-heap.c b/tests/test-heap.c
deleted file mode 100644
index 2bf6e7d..0000000
--- a/tests/test-heap.c
+++ /dev/null
@@ -1,39 +0,0 @@
-#include <telepathy-glib/intset.h>
-#include <telepathy-glib/heap.h>
-
-#include <stdlib.h>
-#include <time.h>
-#include <stdio.h>
-
-static gint comparator_fn (gconstpointer a, gconstpointer b)
-{
-    return (a < b) ? -1 : (a == b) ? 0 : 1;
-}
-
-int
-main (int argc,
-      char **argv)
-{
-  TpHeap *heap = tp_heap_new (comparator_fn, NULL);
-  guint prev = 0;
-  guint i;
-
-  srand (time (NULL));
-
-  for (i=0; i<10000; i++)
-    {
-      tp_heap_add (heap, GUINT_TO_POINTER (rand ()));
-    }
-
-  while (tp_heap_size (heap))
-    {
-      guint elem = GPOINTER_TO_INT (tp_heap_peek_first (heap));
-      g_assert (elem == GPOINTER_TO_UINT (tp_heap_extract_first (heap)));
-      g_assert (prev <= elem);
-      prev = elem;
-    }
-
-  tp_heap_destroy (heap);
-
-  return 0;
-}
diff --git a/tests/test-internal-debug.c b/tests/test-internal-debug.c
deleted file mode 100644
index b852da7..0000000
--- a/tests/test-internal-debug.c
+++ /dev/null
@@ -1,79 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <glib.h>
-
-#include <telepathy-glib/debug.h>
-
-#undef DEBUG_FLAG
-#define DEBUG_FLAG TP_DEBUG_IM
-#include "telepathy-glib/debug-internal.h"
-
-static void
-test_debugging (void)
-{
-#ifndef DEBUG
-#error internal-debug.h should always define DEBUG
-#endif
-
-#ifndef DEBUGGING
-#error internal-debug.h should always define DEBUGGING
-#endif
-
-#ifdef ENABLE_DEBUG
-  g_assert (DEBUGGING == 1);
-#else
-  g_assert (DEBUGGING == 0);
-#endif
-}
-
-#undef DEBUG_FLAG
-#define DEBUG_FLAG TP_DEBUG_CONNECTION
-#include "telepathy-glib/debug-internal.h"
-
-static void
-test_not_debugging (void)
-{
-#ifndef DEBUG
-#error internal-debug.h should always define DEBUG
-#endif
-
-#ifndef DEBUGGING
-#error internal-debug.h should always define DEBUGGING
-#endif
-
-  g_assert (DEBUGGING == 0);
-}
-
-#undef DEBUG_FLAG
-#define DEBUG_FLAG TP_DEBUG_IM
-#include "telepathy-glib/debug-internal.h"
-
-static void
-test_debugging_again (void)
-{
-#ifndef DEBUG
-#error internal-debug.h should always define DEBUG
-#endif
-
-#ifndef DEBUGGING
-#error internal-debug.h should always define DEBUGGING
-#endif
-
-#ifdef ENABLE_DEBUG
-  g_assert (DEBUGGING == 1);
-#else
-  g_assert (DEBUGGING == 0);
-#endif
-}
-
-int
-main (int argc, char **argv)
-{
-  /* We enable debugging for IM, but not for the connection. */
-  tp_debug_set_flags ("im");
-  test_debugging ();
-  test_not_debugging ();
-  test_debugging_again ();
-  return 0;
-}
diff --git a/tests/test-intset.c b/tests/test-intset.c
deleted file mode 100644
index eca52bf..0000000
--- a/tests/test-intset.c
+++ /dev/null
@@ -1,138 +0,0 @@
-#include <glib.h>
-#include <telepathy-glib/intset.h>
-
-int main (int argc, char **argv)
-{
-  TpIntSet *set1 = tp_intset_new ();
-  TpIntSet *a, *b;
-  TpIntSet *ab_union, *ab_expected_union;
-  TpIntSet *ab_inter, *ab_expected_inter;
-  TpIntSet *a_diff_b, *a_expected_diff_b;
-  TpIntSet *b_diff_a, *b_expected_diff_a;
-  TpIntSet *ab_symmdiff, *ab_expected_symmdiff;
-
-  tp_intset_add (set1, 0);
-
-  tp_intset_add (set1, 2);
-  tp_intset_add (set1, 3);
-  tp_intset_add (set1, 5);
-  tp_intset_add (set1, 8);
-
-  tp_intset_add (set1, 1024);
-  tp_intset_add (set1, 32);
-
-  g_assert (tp_intset_size (set1) == 7);
-
-  g_assert (tp_intset_is_member (set1, 2));
-  g_assert (tp_intset_is_member (set1, 5));
-  g_assert (tp_intset_is_member (set1, 1024));
-  g_assert (!tp_intset_is_member (set1, 1023));
-  g_assert (!tp_intset_is_member (set1, 1025));
-  g_assert (tp_intset_is_member (set1, 0));
-  g_assert (tp_intset_is_member (set1, 32));
-  g_assert (!tp_intset_is_member (set1, 31));
-  g_assert (!tp_intset_is_member (set1, 33));
-
-  tp_intset_remove (set1, 8);
-  tp_intset_remove (set1, 1024);
-  g_assert (tp_intset_size (set1) == 5);
-
-  tp_intset_destroy (set1);
-
-#define NUM_A 11
-#define NUM_B 823
-#define NUM_C 367
-#define NUM_D 4177
-#define NUM_E 109
-#define NUM_F 1861
-
-  a = tp_intset_new ();
-  tp_intset_add (a, NUM_A);
-  tp_intset_add (a, NUM_B);
-  tp_intset_add (a, NUM_C);
-  tp_intset_add (a, NUM_D);
-
-  g_assert (tp_intset_is_equal (a, a));
-
-  b = tp_intset_new ();
-  tp_intset_add (b, NUM_C);
-  tp_intset_add (b, NUM_D);
-  tp_intset_add (b, NUM_E);
-  tp_intset_add (b, NUM_F);
-
-  g_assert (tp_intset_is_equal (b, b));
-  g_assert (!tp_intset_is_equal (a, b));
-
-  ab_expected_union = tp_intset_new ();
-  tp_intset_add (ab_expected_union, NUM_A);
-  tp_intset_add (ab_expected_union, NUM_B);
-  tp_intset_add (ab_expected_union, NUM_C);
-  tp_intset_add (ab_expected_union, NUM_D);
-  tp_intset_add (ab_expected_union, NUM_E);
-  tp_intset_add (ab_expected_union, NUM_F);
-
-  ab_union = tp_intset_union (a, b);
-  g_assert (tp_intset_is_equal (ab_union, ab_expected_union));
-  tp_intset_destroy (ab_union);
-  tp_intset_destroy (ab_expected_union);
-
-  ab_expected_inter = tp_intset_new ();
-  tp_intset_add (ab_expected_inter, NUM_C);
-  tp_intset_add (ab_expected_inter, NUM_D);
-
-  ab_inter = tp_intset_intersection (a, b);
-  g_assert (tp_intset_is_equal (ab_inter, ab_expected_inter));
-  tp_intset_destroy (ab_inter);
-  tp_intset_destroy (ab_expected_inter);
-
-  a_expected_diff_b = tp_intset_new ();
-  tp_intset_add (a_expected_diff_b, NUM_A);
-  tp_intset_add (a_expected_diff_b, NUM_B);
-
-  a_diff_b = tp_intset_difference (a, b);
-  g_assert (tp_intset_is_equal (a_diff_b, a_expected_diff_b));
-  tp_intset_destroy (a_diff_b);
-  tp_intset_destroy (a_expected_diff_b);
-
-  b_expected_diff_a = tp_intset_new ();
-  tp_intset_add (b_expected_diff_a, NUM_E);
-  tp_intset_add (b_expected_diff_a, NUM_F);
-
-  b_diff_a = tp_intset_difference (b, a);
-  g_assert (tp_intset_is_equal (b_diff_a, b_expected_diff_a));
-  tp_intset_destroy (b_diff_a);
-  tp_intset_destroy (b_expected_diff_a);
-
-  ab_expected_symmdiff = tp_intset_new ();
-  tp_intset_add (ab_expected_symmdiff, NUM_A);
-  tp_intset_add (ab_expected_symmdiff, NUM_B);
-  tp_intset_add (ab_expected_symmdiff, NUM_E);
-  tp_intset_add (ab_expected_symmdiff, NUM_F);
-
-  ab_symmdiff = tp_intset_symmetric_difference (a, b);
-  g_assert (tp_intset_is_equal (ab_symmdiff, ab_expected_symmdiff));
-  tp_intset_destroy (ab_symmdiff);
-  tp_intset_destroy (ab_expected_symmdiff);
-
-  {
-    GArray *arr;
-    TpIntSet *tmp;
-
-    arr = tp_intset_to_array (a);
-    tmp = tp_intset_from_array (arr);
-    g_assert (tp_intset_is_equal (a, tmp));
-    g_array_free (arr, TRUE);
-    tp_intset_destroy (tmp);
-
-    arr = tp_intset_to_array (b);
-    tmp = tp_intset_from_array (arr);
-    g_assert (tp_intset_is_equal (b, tmp));
-    g_array_free (arr, TRUE);
-    tp_intset_destroy (tmp);
-  }
-
-  tp_intset_destroy (a);
-  tp_intset_destroy (b);
-
-  return 0;
-}
diff --git a/tests/test-util.c b/tests/test-util.c
deleted file mode 100644
index d4b67f1..0000000
--- a/tests/test-util.c
+++ /dev/null
@@ -1,58 +0,0 @@
-#include <stdio.h>
-
-#include <glib.h>
-
-#include <telepathy-glib/util.h>
-
-void test_strv_contains (void);
-
-void
-test_strv_contains (void)
-{
-  const gchar * const strv[] = {
-      "Pah",
-      "Pah",
-      "Pah-pah-pah",
-      "Patrick!",
-      NULL
-  };
-
-  g_assert (tp_strv_contains (strv, "Patrick!"));
-  g_assert (!tp_strv_contains (strv, "Snakes!"));
-}
-
-int main (int argc, char **argv)
-{
-  GPtrArray *ptrarray;
-  gchar *string;
-
-  g_assert (!tp_strdiff (NULL, NULL));
-  g_assert (tp_strdiff ("badger", NULL));
-  g_assert (tp_strdiff (NULL, "badger"));
-  g_assert (!tp_strdiff ("badger", "badger"));
-  g_assert (tp_strdiff ("badger", "mushroom"));
-
-  ptrarray = g_ptr_array_new ();
-  g_ptr_array_add (ptrarray, GINT_TO_POINTER (23));
-  g_ptr_array_add (ptrarray, GINT_TO_POINTER (42));
-  g_assert (tp_g_ptr_array_contains (ptrarray, GINT_TO_POINTER (23)));
-  g_assert (tp_g_ptr_array_contains (ptrarray, GINT_TO_POINTER (42)));
-  g_assert (!tp_g_ptr_array_contains (ptrarray, GINT_TO_POINTER (666)));
-  g_ptr_array_free (ptrarray, TRUE);
-
-  string = tp_escape_as_identifier ("");
-  g_assert (!tp_strdiff (string, "_"));
-  g_free (string);
-
-  string = tp_escape_as_identifier ("badger");
-  g_assert (!tp_strdiff (string, "badger"));
-  g_free (string);
-
-  string = tp_escape_as_identifier ("0123abc_xyz\x01\xff");
-  g_assert (!tp_strdiff (string, "_30123abc_5fxyz_01_ff"));
-  g_free (string);
-
-  test_strv_contains ();
-
-  return 0;
-}
diff --git a/tests/util.c b/tests/util.c
new file mode 100644
index 0000000..d4b67f1
--- /dev/null
+++ b/tests/util.c
@@ -0,0 +1,58 @@
+#include <stdio.h>
+
+#include <glib.h>
+
+#include <telepathy-glib/util.h>
+
+void test_strv_contains (void);
+
+void
+test_strv_contains (void)
+{
+  const gchar * const strv[] = {
+      "Pah",
+      "Pah",
+      "Pah-pah-pah",
+      "Patrick!",
+      NULL
+  };
+
+  g_assert (tp_strv_contains (strv, "Patrick!"));
+  g_assert (!tp_strv_contains (strv, "Snakes!"));
+}
+
+int main (int argc, char **argv)
+{
+  GPtrArray *ptrarray;
+  gchar *string;
+
+  g_assert (!tp_strdiff (NULL, NULL));
+  g_assert (tp_strdiff ("badger", NULL));
+  g_assert (tp_strdiff (NULL, "badger"));
+  g_assert (!tp_strdiff ("badger", "badger"));
+  g_assert (tp_strdiff ("badger", "mushroom"));
+
+  ptrarray = g_ptr_array_new ();
+  g_ptr_array_add (ptrarray, GINT_TO_POINTER (23));
+  g_ptr_array_add (ptrarray, GINT_TO_POINTER (42));
+  g_assert (tp_g_ptr_array_contains (ptrarray, GINT_TO_POINTER (23)));
+  g_assert (tp_g_ptr_array_contains (ptrarray, GINT_TO_POINTER (42)));
+  g_assert (!tp_g_ptr_array_contains (ptrarray, GINT_TO_POINTER (666)));
+  g_ptr_array_free (ptrarray, TRUE);
+
+  string = tp_escape_as_identifier ("");
+  g_assert (!tp_strdiff (string, "_"));
+  g_free (string);
+
+  string = tp_escape_as_identifier ("badger");
+  g_assert (!tp_strdiff (string, "badger"));
+  g_free (string);
+
+  string = tp_escape_as_identifier ("0123abc_xyz\x01\xff");
+  g_assert (!tp_strdiff (string, "_30123abc_5fxyz_01_ff"));
+  g_free (string);
+
+  test_strv_contains ();
+
+  return 0;
+}
-- 
1.5.6.5




More information about the telepathy-commits mailing list