# HG changeset patch
# Node ID b6a32171d9b98af8d3a6950e7c6f3f4ea649caf1
# Parent  59e6529a1e788166a4c6f31ad31885fd841e13ae
diff --git a/libpurple/purpleprotocolcontacts.c b/libpurple/purpleprotocolcontacts.c
--- a/libpurple/purpleprotocolcontacts.c
+++ b/libpurple/purpleprotocolcontacts.c
@@ -107,8 +107,11 @@
 		iface->search_async(protocol_contacts, account, text, cancellable,
 		                    callback, data);
 	} else {
-		g_warning("%s does not implement search_async",
-		          G_OBJECT_TYPE_NAME(protocol_contacts));
+		g_task_report_new_error(G_OBJECT(protocol_contacts), callback, data,
+		                        purple_protocol_contacts_search_async,
+		                        PURPLE_PROTOCOL_CONTACTS_DOMAIN, 0,
+		                        "%s does not implement search_async",
+		                        G_OBJECT_TYPE_NAME(protocol_contacts));
 	}
 }
 
@@ -120,6 +123,12 @@
 	PurpleProtocolContactsInterface *iface = NULL;
 
 	g_return_val_if_fail(PURPLE_IS_PROTOCOL_CONTACTS(protocol_contacts), NULL);
+	g_return_val_if_fail(G_IS_ASYNC_RESULT(result), NULL);
+
+	if(g_async_result_is_tagged(result, purple_protocol_contacts_search_async))
+	{
+		return g_task_propagate_pointer(G_TASK(result), error);
+	}
 
 	iface = PURPLE_PROTOCOL_CONTACTS_GET_IFACE(protocol_contacts);
 	if(iface != NULL && iface->search_finish != NULL) {
@@ -145,11 +154,13 @@
 			            G_OBJECT_TYPE_NAME(protocol_contacts),
 			            g_type_name(type));
 		}
-	} else {
-		g_warning("%s does not implement search_finish",
-		          G_OBJECT_TYPE_NAME(protocol_contacts));
+
+		return ret;
 	}
 
+	g_warning("purple_protocol_contacts_search_finish called without calling "
+	          "purple_protocol_contacts_search_async");
+
 	return NULL;
 }
 
@@ -170,8 +181,11 @@
 		iface->get_profile_async(protocol_contacts, info, cancellable,
 		                         callback, data);
 	} else {
-		g_warning("%s does not implement get_profile_async",
-		          G_OBJECT_TYPE_NAME(protocol_contacts));
+		g_task_report_new_error(G_OBJECT(protocol_contacts), callback, data,
+		                        purple_protocol_contacts_get_profile_async,
+		                        PURPLE_PROTOCOL_CONTACTS_DOMAIN, 0,
+		                        "%s does not implement get_profile_async",
+		                        G_OBJECT_TYPE_NAME(protocol_contacts));
 	}
 }
 
@@ -183,15 +197,22 @@
 	PurpleProtocolContactsInterface *iface = NULL;
 
 	g_return_val_if_fail(PURPLE_IS_PROTOCOL_CONTACTS(protocol_contacts), NULL);
+	g_return_val_if_fail(G_IS_ASYNC_RESULT(result), NULL);
+
+	if(g_async_result_is_tagged(result,
+	                            purple_protocol_contacts_get_profile_async))
+	{
+		return g_task_propagate_pointer(G_TASK(result), error);
+	}
 
 	iface = PURPLE_PROTOCOL_CONTACTS_GET_IFACE(protocol_contacts);
 	if(iface != NULL && iface->get_profile_finish != NULL) {
 		return iface->get_profile_finish(protocol_contacts, result, error);
-	} else {
-		g_warning("%s does not implement get_profile_finish",
-		          G_OBJECT_TYPE_NAME(protocol_contacts));
 	}
 
+	g_warning("purple_protocol_contacts_get_profile_finish without calling "
+	          "purple_protocol_contacts_get_profile_async");
+
 	return NULL;
 }
 
diff --git a/libpurple/tests/test_protocol_contacts.c b/libpurple/tests/test_protocol_contacts.c
--- a/libpurple/tests/test_protocol_contacts.c
+++ b/libpurple/tests/test_protocol_contacts.c
@@ -100,93 +100,81 @@
 }
 
 static void
-test_purple_protocol_contacts_empty_search_async(void) {
-	if(g_test_subprocess()) {
-		PurpleAccount *account = NULL;
-		PurpleProtocolContacts *protocol = NULL;
-
-		protocol = g_object_new(test_purple_protocol_contacts_empty_get_type(),
-		                        NULL);
+test_purple_protocol_contacts_empty_search_cb(GObject *source,
+                                              GAsyncResult *result,
+                                              G_GNUC_UNUSED gpointer data)
+{
+	PurpleProtocolContacts *protocol = NULL;
+	GError *error = NULL;
+	GListModel *model = NULL;
 
-		account = purple_account_new("test", "test");
-		purple_protocol_contacts_search_async(protocol, account, "alice", NULL,
-		                                      NULL, NULL);
+	g_assert_true(PURPLE_IS_PROTOCOL_CONTACTS(source));
+
+	protocol = PURPLE_PROTOCOL_CONTACTS(source);
 
-		g_clear_object(&account);
-		g_clear_object(&protocol);
-	}
-
-	g_test_trap_subprocess(NULL, 0, 0);
-	g_test_trap_assert_stderr("*Purple-WARNING*TestPurpleProtocolContactsEmpty*search_async*");
+	model = purple_protocol_contacts_search_finish(protocol, result, &error);
+	g_assert_error(error, PURPLE_PROTOCOL_CONTACTS_DOMAIN, 0);
+	g_clear_error(&error);
+	g_assert_null(model);
 }
 
 static void
-test_purple_protocol_contacts_empty_search_finish(void) {
-	if(g_test_subprocess()) {
-		PurpleProtocolContacts *protocol = NULL;
-		GTask *task = NULL;
+test_purple_protocol_contacts_empty_search_async(void) {
+	PurpleAccount *account = NULL;
+	PurpleProtocolContacts *protocol = NULL;
+
+	protocol = g_object_new(test_purple_protocol_contacts_empty_get_type(),
+	                        NULL);
 
-		protocol = g_object_new(test_purple_protocol_contacts_empty_get_type(),
-		                        NULL);
+	account = purple_account_new("test", "test");
+	purple_protocol_contacts_search_async(protocol, account, "alice", NULL,
+	                                      test_purple_protocol_contacts_empty_search_cb,
+	                                      NULL);
+
+	g_main_context_iteration(NULL, FALSE);
+
+	g_assert_finalize_object(account);
+	g_assert_finalize_object(protocol);
+}
 
-		task = g_task_new(protocol, NULL, NULL, NULL);
-		purple_protocol_contacts_search_finish(protocol, G_ASYNC_RESULT(task),
-		                                       NULL);
+static void
+test_purple_protocol_contacts_empty_get_profile_cb(GObject *source,
+                                                   GAsyncResult *result,
+                                                   G_GNUC_UNUSED gpointer data)
+{
+	PurpleProtocolContacts *protocol = NULL;
+	GError *error = NULL;
+	char *profile = NULL;
 
-		g_clear_object(&task);
-		g_clear_object(&protocol);
-	}
+	g_assert_true(PURPLE_IS_PROTOCOL_CONTACTS(source));
+
+	protocol = PURPLE_PROTOCOL_CONTACTS(source);
 
-	g_test_trap_subprocess(NULL, 0, 0);
-	g_test_trap_assert_stderr("*Purple-WARNING*TestPurpleProtocolContactsEmpty*search_finish*");
+	profile = purple_protocol_contacts_get_profile_finish(protocol, result,
+	                                                      &error);
+	g_assert_error(error, PURPLE_PROTOCOL_CONTACTS_DOMAIN, 0);
+	g_clear_error(&error);
+	g_assert_null(profile);
 }
 
 static void
 test_purple_protocol_contacts_empty_get_profile_async(void) {
-	if(g_test_subprocess()) {
-		PurpleContactInfo *info = NULL;
-		PurpleProtocolContacts *protocol_contacts = NULL;
-
-		protocol_contacts = g_object_new(test_purple_protocol_contacts_empty_get_type(),
-		                                 NULL);
-		info = purple_contact_info_new(NULL);
+	PurpleContactInfo *info = NULL;
+	PurpleProtocolContacts *protocol_contacts = NULL;
 
-		purple_protocol_contacts_get_profile_async(protocol_contacts, info,
-		                                           NULL, NULL, NULL);
-
-		g_clear_object(&info);
-		g_clear_object(&protocol_contacts);
-	}
-
-	g_test_trap_subprocess(NULL, 0, 0);
-	g_test_trap_assert_stderr("*Purple-WARNING*TestPurpleProtocolContactsEmpty*get_profile_async*");
-}
+	protocol_contacts = g_object_new(test_purple_protocol_contacts_empty_get_type(),
+	                                 NULL);
+	info = purple_contact_info_new(NULL);
 
-static void
-test_purple_protocol_contacts_empty_get_profile_finish(void) {
-	if(g_test_subprocess()) {
-		PurpleProtocolContacts *protocol_contacts = NULL;
-		GError *error = NULL;
-		GTask *task = NULL;
-		char *result = NULL;
-
-		protocol_contacts = g_object_new(test_purple_protocol_contacts_empty_get_type(),
-		                                 NULL);
-
-		task = g_task_new(protocol_contacts, NULL, NULL, NULL);
+	purple_protocol_contacts_get_profile_async(protocol_contacts, info,
+	                                           NULL,
+	                                           test_purple_protocol_contacts_empty_get_profile_cb,
+	                                           NULL);
 
-		result = purple_protocol_contacts_get_profile_finish(protocol_contacts,
-		                                                     G_ASYNC_RESULT(task),
-		                                                     &error);
-		g_assert_no_error(error);
-		g_assert_false(result);
+	g_main_context_iteration(NULL, FALSE);
 
-		g_clear_object(&task);
-		g_clear_object(&protocol_contacts);
-	}
-
-	g_test_trap_subprocess(NULL, 0, 0);
-	g_test_trap_assert_stderr("*Purple-WARNING*TestPurpleProtocolContactsEmpty*get_profile_finish*");
+	g_assert_finalize_object(info);
+	g_assert_finalize_object(protocol_contacts);
 }
 
 static void
@@ -611,6 +599,8 @@
 
 	g_test_init(&argc, &argv, NULL);
 
+	g_test_set_nonfatal_assertions();
+
 	test_ui_purple_init();
 
 	loop = g_main_loop_new(NULL, FALSE);
@@ -619,12 +609,8 @@
 	                test_purple_protocol_contacts_empty_get_minimum_search_length);
 	g_test_add_func("/protocol-contacts/empty/search-async",
 	                test_purple_protocol_contacts_empty_search_async);
-	g_test_add_func("/protocol-contacts/empty/search-finish",
-	                test_purple_protocol_contacts_empty_search_finish);
 	g_test_add_func("/protocol-contacts/empty/get-profile-async",
 	                test_purple_protocol_contacts_empty_get_profile_async);
-	g_test_add_func("/protocol-contacts/empty/get-profile-finish",
-	                test_purple_protocol_contacts_empty_get_profile_finish);
 	g_test_add_func("/protocol-contacts/empty/get-actions",
 	                test_purple_protocol_contacts_empty_get_actions);
 	g_test_add_func("/protocol-contacts/empty/get-menu",
