From eb5b04df46236d1633f012ef003e08a49b1f18c6 Mon Sep 17 00:00:00 2001 From: James Booth Date: Fri, 18 May 2012 01:33:40 +0100 Subject: [PATCH] Autocomplte uses default functions --- Makefile | 3 +- contact.c | 14 +++++ contact.h | 1 + prof_autocomplete.c | 34 ++++++---- test_prof_autocomplete.c | 133 +++++++++++++++++++++++++++++++++++++++ testsuite.c | 1 + testsuite.h | 1 + 7 files changed, 173 insertions(+), 14 deletions(-) create mode 100644 test_prof_autocomplete.c diff --git a/Makefile b/Makefile index 1a8d1675..88dc5973 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ OBJS = log.o windows.o title_bar.o status_bar.o input_win.o jabber.o \ contact.o preferences.o prof_autocomplete.o main.o TESTOBJS = test_contact_list.o contact_list.o contact.o \ test_util.o test_prof_history.o prof_history.o util.o \ - prof_autocomplete.o + test_prof_autocomplete.o prof_autocomplete.o profanity: $(OBJS) $(CC) -o profanity $(OBJS) $(LIBS) @@ -36,6 +36,7 @@ main.o: profanity.h test_contact_list.o: contact_list.h contact.h test_util.o: util.h test_prof_history.o: prof_history.h +test_prof_autocomplete.o: contact.h prof_autocomplete.h testsuite: testsuite.h $(TESTOBJS) $(CC) $(CFLAGS) $(CPPLIB) testsuite.c $(TESTOBJS) -o testsuite $(TESTLIB) diff --git a/contact.c b/contact.c index bc0f8344..79950e80 100644 --- a/contact.c +++ b/contact.c @@ -50,6 +50,20 @@ PContact p_contact_new(const char * const name, const char * const show, return contact; } +PContact p_contact_copy(PContact contact) +{ + PContact copy = malloc(sizeof(struct p_contact_t)); + copy->name = strdup(contact->name); + copy->show = strdup(contact->show); + + if (contact->status != NULL) + copy->status = strdup(contact->status); + else + copy->status = NULL; + + return copy; +} + void p_contact_free(PContact contact) { free(contact->name); diff --git a/contact.h b/contact.h index 195acf40..3b997a0e 100644 --- a/contact.h +++ b/contact.h @@ -27,6 +27,7 @@ typedef struct p_contact_t *PContact; PContact p_contact_new(const char * const name, const char * const show, const char * const status); +PContact p_contact_copy(PContact contact); void p_contact_free(PContact contact); const char * p_contact_name(PContact contact); const char * p_contact_show(PContact contact); diff --git a/prof_autocomplete.c b/prof_autocomplete.c index 5d4e90d8..85e78862 100644 --- a/prof_autocomplete.c +++ b/prof_autocomplete.c @@ -33,8 +33,8 @@ struct p_autocomplete_t { gchar *search_str; }; - static gchar * _search_from(PAutocomplete ac, GSList *curr, PStrFunc str_func); +static const char *_str_func_default(const char *orig); PAutocomplete p_autocomplete_new(void) { @@ -66,6 +66,9 @@ void p_autocomplete_reset(PAutocomplete ac) void p_autocomplete_add(PAutocomplete ac, void *item, PStrFunc str_func, GDestroyNotify free_func) { + if (str_func == NULL) + str_func = (PStrFunc)_str_func_default; + if (ac->items == NULL) { ac->items = g_slist_append(ac->items, item); return; @@ -75,15 +78,13 @@ void p_autocomplete_add(PAutocomplete ac, void *item, PStrFunc str_func, while(curr) { // insert - if ( ((str_func == NULL) && (g_strcmp0(curr->data, item) > 0)) || - ((g_strcmp0(str_func(curr->data), str_func(item)) > 0)) ) { + if (g_strcmp0(str_func(curr->data), str_func(item)) > 0) { ac->items = g_slist_insert_before(ac->items, curr, item); return; // update - } else if ( ((str_func == NULL) && (g_strcmp0(curr->data, item) == 0)) || - ((g_strcmp0(str_func(curr->data), str_func(item)) == 0)) ) { + } else if (g_strcmp0(str_func(curr->data), str_func(item)) == 0) { free_func(curr->data); curr->data = item; return; @@ -102,10 +103,12 @@ void p_autocomplete_add(PAutocomplete ac, void *item, PStrFunc str_func, void p_autocomplete_remove(PAutocomplete ac, const char * const item, PStrFunc str_func, GDestroyNotify free_func) { + if (str_func == NULL) + str_func = (PStrFunc)_str_func_default; + // reset last found if it points to the item to be removed if (ac->last_found != NULL) - if ( ((str_func == NULL) && (g_strcmp0(ac->last_found->data, item) == 0)) || - ((g_strcmp0(str_func(ac->last_found->data), item) == 0)) ) + if (g_strcmp0(str_func(ac->last_found->data), item) == 0) ac->last_found = NULL; if (!ac->items) { @@ -114,8 +117,7 @@ void p_autocomplete_remove(PAutocomplete ac, const char * const item, GSList *curr = ac->items; while(curr) { - if ( ((str_func == NULL) && (g_strcmp0(curr->data, item) == 0)) || - ((g_strcmp0(str_func(curr->data), item) == 0)) ) { + if (g_strcmp0(str_func(curr->data), item) == 0) { void *current_item = curr->data; ac->items = g_slist_remove(ac->items, curr->data); free_func(current_item); @@ -146,6 +148,9 @@ GSList * p_autocomplete_get_list(PAutocomplete ac, PCopyFunc copy_func) gchar * p_autocomplete_complete(PAutocomplete ac, gchar *search_str, PStrFunc str_func) { + if (str_func == NULL) + str_func = (PStrFunc)_str_func_default; + gchar *found = NULL; // no items to search @@ -184,11 +189,9 @@ static gchar * _search_from(PAutocomplete ac, GSList *curr, PStrFunc str_func) while(curr) { // match found - if ( ( (str_func == NULL) && (strncmp(curr->data, ac->search_str, - strlen(ac->search_str)) == 0) ) || - ( (strncmp(str_func(curr->data), + if (strncmp(str_func(curr->data), ac->search_str, - strlen(ac->search_str)) == 0) ) ) { + strlen(ac->search_str)) == 0) { gchar *result = (gchar *) malloc((strlen(str_func(curr->data)) + 1) * sizeof(gchar)); @@ -206,3 +209,8 @@ static gchar * _search_from(PAutocomplete ac, GSList *curr, PStrFunc str_func) return NULL; } +static const char *_str_func_default(const char *orig) +{ + return orig; +} + diff --git a/test_prof_autocomplete.c b/test_prof_autocomplete.c new file mode 100644 index 00000000..7d078575 --- /dev/null +++ b/test_prof_autocomplete.c @@ -0,0 +1,133 @@ +#include +#include +#include + +#include "contact.h" +#include "prof_autocomplete.h" + +static void clear_empty(void) +{ + PAutocomplete ac = p_autocomplete_new(); + p_autocomplete_clear(ac, NULL); +} + +static void clear_empty_with_free_func(void) +{ + PAutocomplete ac = p_autocomplete_new(); + p_autocomplete_clear(ac, (GDestroyNotify)p_contact_free); +} + +static void reset_after_create(void) +{ + PAutocomplete ac = p_autocomplete_new(); + p_autocomplete_reset(ac); + p_autocomplete_clear(ac, NULL); +} + +static void find_after_create(void) +{ + PAutocomplete ac = p_autocomplete_new(); + p_autocomplete_complete(ac, "hello", NULL); + p_autocomplete_clear(ac, NULL); +} + +static void get_after_create_returns_null(void) +{ + PAutocomplete ac = p_autocomplete_new(); + p_autocomplete_get_list(ac, NULL); + p_autocomplete_clear(ac, NULL); +} + +static void get_after_create_with_copy_func_returns_null(void) +{ + PAutocomplete ac = p_autocomplete_new(); + p_autocomplete_get_list(ac, (PCopyFunc)p_contact_copy); + p_autocomplete_clear(ac, NULL); +} + +static void add_one_and_complete(void) +{ + PAutocomplete ac = p_autocomplete_new(); + p_autocomplete_add(ac, "Hello", NULL, NULL); + char *result = p_autocomplete_complete(ac, "Hel", NULL); + + assert_string_equals("Hello", result); +} + +static void add_one_and_complete_with_funcs(void) +{ + PContact contact = p_contact_new("James", "Online", "I'm here"); + PAutocomplete ac = p_autocomplete_new(); + p_autocomplete_add(ac, contact, (PStrFunc)p_contact_name, + (GDestroyNotify)p_contact_free); + char *result = p_autocomplete_complete(ac, "Jam", (PStrFunc)p_contact_name); + + assert_string_equals("James", result); +} + +static void add_two_and_complete_returns_first(void) +{ + PAutocomplete ac = p_autocomplete_new(); + p_autocomplete_add(ac, "Hello", NULL, NULL); + p_autocomplete_add(ac, "Help", NULL, NULL); + char *result = p_autocomplete_complete(ac, "Hel", NULL); + + assert_string_equals("Hello", result); +} + +static void add_two_and_complete_returns_first_with_funcs(void) +{ + PContact contact1 = p_contact_new("James", "Online", "I'm here"); + PContact contact2 = p_contact_new("Jamie", "Away", "Out to lunch"); + PAutocomplete ac = p_autocomplete_new(); + p_autocomplete_add(ac, contact1, (PStrFunc)p_contact_name, + (GDestroyNotify)p_contact_free); + p_autocomplete_add(ac, contact2, (PStrFunc)p_contact_name, + (GDestroyNotify)p_contact_free); + char *result = p_autocomplete_complete(ac, "Jam", (PStrFunc)p_contact_name); + + assert_string_equals("James", result); +} + +static void add_two_and_complete_returns_second(void) +{ + PAutocomplete ac = p_autocomplete_new(); + p_autocomplete_add(ac, "Hello", NULL, NULL); + p_autocomplete_add(ac, "Help", NULL, NULL); + char *result1 = p_autocomplete_complete(ac, "Hel", NULL); + char *result2 = p_autocomplete_complete(ac, result1, NULL); + + assert_string_equals("Help", result2); +} + +static void add_two_and_complete_returns_second_with_funcs(void) +{ + PContact contact1 = p_contact_new("James", "Online", "I'm here"); + PContact contact2 = p_contact_new("Jamie", "Away", "Out to lunch"); + PAutocomplete ac = p_autocomplete_new(); + p_autocomplete_add(ac, contact1, (PStrFunc)p_contact_name, + (GDestroyNotify)p_contact_free); + p_autocomplete_add(ac, contact2, (PStrFunc)p_contact_name, + (GDestroyNotify)p_contact_free); + char *result1 = p_autocomplete_complete(ac, "Jam", (PStrFunc)p_contact_name); + char *result2 = p_autocomplete_complete(ac, result1, (PStrFunc)p_contact_name); + + assert_string_equals("Jamie", result2); +} + +void register_prof_autocomplete_tests(void) +{ + TEST_MODULE("prof_autocomplete tests"); + TEST(clear_empty); + TEST(clear_empty_with_free_func); + TEST(reset_after_create); + TEST(find_after_create); + TEST(get_after_create_returns_null); + TEST(get_after_create_with_copy_func_returns_null); + TEST(add_one_and_complete); + TEST(add_one_and_complete_with_funcs); + TEST(add_two_and_complete_returns_first); + TEST(add_two_and_complete_returns_first_with_funcs); + TEST(add_two_and_complete_returns_second); + TEST(add_two_and_complete_returns_second_with_funcs); +} diff --git a/testsuite.c b/testsuite.c index e6eb6d0b..c3f164f9 100644 --- a/testsuite.c +++ b/testsuite.c @@ -6,6 +6,7 @@ int main(void) register_prof_history_tests(); register_contact_list_tests(); register_util_tests(); + register_prof_autocomplete_tests(); run_suite(); return 0; } diff --git a/testsuite.h b/testsuite.h index 410b3e47..f4bd9046 100644 --- a/testsuite.h +++ b/testsuite.h @@ -4,5 +4,6 @@ void register_prof_history_tests(void); void register_contact_list_tests(void); void register_util_tests(void); +void register_prof_autocomplete_tests(void); #endif