Sat, 09 Aug 2025 17:37:27 +0800
Fix the birb header path
The birb header referred would only work with birb provided by wrap casuing
build to fail because of system-installed birb dependency. The commit points
it to the correct path <birb.h>.
See: https://keep.imfreedom.org/birb/birb/file/5bf00c7d7f80/birb/meson.build#l77
/* * Purple - Internet Messaging Library * Copyright (C) Pidgin Developers <devel@pidgin.im> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see <https://www.gnu.org/licenses/>. */ #include <glib.h> #include <birb.h> #include <purple.h> /****************************************************************************** * Tests *****************************************************************************/ static void test_purple_command_manager_new(void) { PurpleCommandManager *manager = NULL; manager = purple_command_manager_new(); g_assert_true(PURPLE_IS_COMMAND_MANAGER(manager)); g_assert_finalize_object(manager); } static void test_purple_command_manager_add_remove(void) { PurpleCommand *command = NULL; PurpleCommandManager *manager = NULL; GListModel *model = NULL; gboolean ret = FALSE; guint counter = 0; manager = purple_command_manager_new(); model = G_LIST_MODEL(manager); birb_count_list_model_items_changed(G_LIST_MODEL(manager), &counter); g_assert_cmpuint(g_list_model_get_n_items(model), ==, 0); command = purple_command_new("test-command", "test", 0); /* We use command again in the next test. */ g_object_ref(command); purple_command_manager_add(manager, command); g_assert_cmpuint(g_list_model_get_n_items(model), ==, 1); g_assert_cmpuint(counter, ==, 1); /* Duplicate adds should be ignore. */ counter = 0; purple_command_manager_add(manager, command); g_assert_cmpuint(g_list_model_get_n_items(model), ==, 1); g_assert_cmpuint(counter, ==, 0); /* Duplicate command but as a new pointer and make sure it doesn't get * added. */ counter = 0; command = purple_command_new("test-command", "test", 0); purple_command_manager_add(manager, command); g_assert_cmpuint(g_list_model_get_n_items(model), ==, 1); g_assert_cmpuint(counter, ==, 0); /* Name and command must match. */ counter = 0; ret = purple_command_manager_remove(manager, "unknown-command", "test"); g_assert_false(ret); g_assert_cmpuint(g_list_model_get_n_items(model), ==, 1); g_assert_cmpuint(counter, ==, 0); counter = 0; ret = purple_command_manager_remove(manager, "test-command", "unknown"); g_assert_false(ret); g_assert_cmpuint(g_list_model_get_n_items(model), ==, 1); g_assert_cmpuint(counter, ==, 0); /* Do the real remove. */ counter = 0; ret = purple_command_manager_remove(manager, "test-command", "test"); g_assert_true(ret); g_assert_cmpuint(g_list_model_get_n_items(model), ==, 0); g_assert_cmpuint(counter, ==, 1); /* Duplicate removes should return false as the item is gone. */ counter = 0; ret = purple_command_manager_remove(manager, "test-command", "test"); g_assert_false(ret); g_assert_cmpuint(g_list_model_get_n_items(model), ==, 0); g_assert_cmpuint(counter, ==, 0); g_assert_finalize_object(manager); } static void test_purple_command_manager_remove_all_with_source(void) { PurpleCommand *command = NULL; PurpleCommandManager *manager = NULL; GListModel *model = NULL; guint counter = 0; manager = purple_command_manager_new(); model = G_LIST_MODEL(manager); birb_count_list_model_items_changed(G_LIST_MODEL(manager), &counter); /* Make sure remove all works on an empty manager. */ counter = 0; purple_command_manager_remove_all_with_source(manager, "test-1"); g_assert_cmpuint(g_list_model_get_n_items(model), ==, 0); g_assert_cmpuint(counter, ==, 0); /* Add 3 commands, two with the same source and another with a different * source in between them. */ command = purple_command_new("privmsg", "test-1", 0); purple_command_manager_add(manager, command); command = purple_command_new("xyzzy", "test-2", 0); purple_command_manager_add(manager, command); command = purple_command_new("query", "test-1", 0); purple_command_manager_add(manager, command); g_assert_cmpuint(g_list_model_get_n_items(model), ==, 3); /* Remove the commands with test-1 as a source and verify that the second * command still exists. */ counter = 0; purple_command_manager_remove_all_with_source(manager, "test-1"); g_assert_cmpuint(g_list_model_get_n_items(model), ==, 1); g_assert_cmpuint(counter, ==, 2); command = purple_command_manager_find(manager, NULL, "xyzzy"); g_assert_true(PURPLE_IS_COMMAND(command)); /* Add another command with a source of test-2. */ command = purple_command_new("quit", "test-2", 0); purple_command_manager_add(manager, command); g_assert_cmpuint(g_list_model_get_n_items(model), ==, 2); /* Now remove all commands with a source of test-2. */ counter = 0; purple_command_manager_remove_all_with_source(manager, "test-2"); g_assert_cmpuint(g_list_model_get_n_items(model), ==, 0); g_assert_cmpuint(counter, ==, 2); g_assert_finalize_object(manager); } static void test_purple_command_manager_find(void) { PurpleCommand *command = NULL; PurpleCommandManager *manager = NULL; PurpleConversation *conversation = NULL; PurpleTags *tags = NULL; manager = purple_command_manager_new(); /* We need at least one conversation to test filtering, so we just create * one with a tag of test=true. */ conversation = g_object_new(PURPLE_TYPE_CONVERSATION, NULL); tags = purple_conversation_get_tags(conversation); purple_tags_add(tags, "test=true"); /* Test that find works with nothing added. This is unlikely to happen in * practice, but it's good to test for. */ command = purple_command_manager_find(manager, NULL, "unknown"); g_assert_null(command); command = purple_command_manager_find(manager, conversation, "unknown"); g_assert_null(command); /* Now add a test command and verify that we can find it. */ command = purple_command_new("test", "test-1", 0); tags = purple_command_get_tags(command); purple_tags_add(tags, "test=true"); purple_command_manager_add(manager, command); command = purple_command_manager_find(manager, NULL, "test"); g_assert_true(PURPLE_IS_COMMAND(command)); command = purple_command_manager_find(manager, conversation, "test"); g_assert_true(PURPLE_IS_COMMAND(command)); /* Now add the command again but with a lower priority. */ command = purple_command_new("test", "test-2", -100); tags = purple_command_get_tags(command); purple_tags_add(tags, "test=true"); purple_command_manager_add(manager, command); command = purple_command_manager_find(manager, NULL, "test"); g_assert_true(PURPLE_IS_COMMAND(command)); g_assert_cmpuint(purple_command_get_priority(command), ==, 0); command = purple_command_manager_find(manager, conversation, "test"); g_assert_true(PURPLE_IS_COMMAND(command)); g_assert_cmpuint(purple_command_get_priority(command), ==, 0); /* Now add the command again but with a higher priority. */ command = purple_command_new("test", "test-3", 100); tags = purple_command_get_tags(command); purple_tags_add(tags, "test=true"); purple_command_manager_add(manager, command); command = purple_command_manager_find(manager, NULL, "test"); g_assert_true(PURPLE_IS_COMMAND(command)); g_assert_cmpuint(purple_command_get_priority(command), ==, 100); command = purple_command_manager_find(manager, conversation, "test"); g_assert_true(PURPLE_IS_COMMAND(command)); g_assert_cmpuint(purple_command_get_priority(command), ==, 100); /* Finally add the command again, but with a much higher priority and tags * that won't match the conversation. */ command = purple_command_new("test", "test-4", 1337); tags = purple_command_get_tags(command); purple_tags_add(tags, "test=false"); purple_command_manager_add(manager, command); command = purple_command_manager_find(manager, NULL, "test"); g_assert_true(PURPLE_IS_COMMAND(command)); g_assert_cmpuint(purple_command_get_priority(command), ==, 1337); command = purple_command_manager_find(manager, conversation, "test"); g_assert_true(PURPLE_IS_COMMAND(command)); g_assert_cmpuint(purple_command_get_priority(command), ==, 100); /* Cleanup. */ g_assert_finalize_object(conversation); g_assert_finalize_object(manager); } static void test_purple_command_manager_find_all(void) { PurpleCommand *command = NULL; PurpleCommandManager *manager = NULL; PurpleConversation *conversation = NULL; PurpleTags *tags = NULL; GListModel *commands = NULL; manager = purple_command_manager_new(); /* We need at least one conversation to test filtering, so we just create * one with a tag of test=true. */ conversation = g_object_new(PURPLE_TYPE_CONVERSATION, NULL); tags = purple_conversation_get_tags(conversation); purple_tags_add(tags, "test=true"); /* Create and add our commands that all share a name. One with no tags, * another with the same tags as the conversation, one without the * conversation tags, and another with a different priority but the * conversation tags. */ command = purple_command_new("test", "test-1", 0); purple_command_manager_add(manager, command); command = purple_command_new("test", "test-2", 0); tags = purple_command_get_tags(command); purple_tags_add(tags, "test=true"); purple_command_manager_add(manager, command); command = purple_command_new("test", "test-3", 0); tags = purple_command_get_tags(command); purple_tags_add(tags, "test=false"); purple_command_manager_add(manager, command); command = purple_command_new("test", "test-4", 100); tags = purple_command_get_tags(command); purple_tags_add(tags, "test=true"); purple_command_manager_add(manager, command); /* Check an unknown command. */ commands = purple_command_manager_find_all(manager, NULL, "unknown"); g_assert_cmpuint(g_list_model_get_n_items(commands), ==, 0); g_clear_object(&commands); /* Check without the conversation. */ commands = purple_command_manager_find_all(manager, NULL, "test"); g_assert_cmpuint(g_list_model_get_n_items(commands), ==, 4); g_clear_object(&commands); /* Check with the conversation. */ commands = purple_command_manager_find_all(manager, conversation, "test"); g_assert_cmpuint(g_list_model_get_n_items(commands), ==, 3); g_clear_object(&commands); g_assert_finalize_object(conversation); g_assert_finalize_object(manager); } /****************************************************************************** * Find and Execute tests *****************************************************************************/ static void test_purple_command_manager_find_and_execute_counter(PurpleCommand *command, PurpleConversation *conversation, G_GNUC_UNUSED GStrv params, gpointer data) { guint *counter = data; g_assert_true(PURPLE_IS_COMMAND(command)); g_assert_true(PURPLE_IS_CONVERSATION(conversation)); *counter = *counter + 1; } static void test_purple_command_manager_find_and_execute_executed(PurpleCommand *command, PurpleConversation *conversation, GStrv params, gpointer data) { g_assert_true(PURPLE_IS_COMMAND(command)); g_assert_true(PURPLE_IS_CONVERSATION(conversation)); g_assert_cmpstrv(params, data); } static void test_purple_command_manager_find_and_execute(void) { PurpleCommand *command = NULL; PurpleCommandManager *manager = NULL; PurpleConversation *conversation = NULL; gboolean result = FALSE; guint counter = 0; const char * const expected_args[] = {"arg1", "arg2", NULL}; manager = purple_command_manager_new(); conversation = g_object_new(PURPLE_TYPE_CONVERSATION, NULL); /* Make sure we can't find anything in an empty manager. */ result = purple_command_manager_find_and_execute(manager, conversation, "unknown"); g_assert_false(result); /* Again but with some arguments this time. */ result = purple_command_manager_find_and_execute(manager, conversation, "unknown arg1 arg2"); g_assert_false(result); /* Create and add the command. */ command = purple_command_new("test", "test-1", 0); g_signal_connect(command, "executed", G_CALLBACK(test_purple_command_manager_find_and_execute_counter), &counter); g_signal_connect(command, "executed", G_CALLBACK(test_purple_command_manager_find_and_execute_executed), (gpointer)expected_args); purple_command_manager_add(manager, command); /* Try to execute it. */ counter = 0; result = purple_command_manager_find_and_execute(manager, conversation, "test arg1 arg2"); g_assert_true(result); g_assert_cmpuint(counter, ==, 1); g_assert_finalize_object(conversation); g_assert_finalize_object(manager); } /****************************************************************************** * Main *****************************************************************************/ int main(int argc, char *argv[]) { g_test_init(&argc, &argv, NULL); g_test_set_nonfatal_assertions(); g_test_add_func("/command-manager/new", test_purple_command_manager_new); g_test_add_func("/command-manager/add-remove", test_purple_command_manager_add_remove); g_test_add_func("/command-manager/remove-all-with-source", test_purple_command_manager_remove_all_with_source); g_test_add_func("/command-manager/find", test_purple_command_manager_find); g_test_add_func("/command-manager/find-all", test_purple_command_manager_find_all); g_test_add_func("/command-manager/find-and-execute", test_purple_command_manager_find_and_execute); return g_test_run(); }