From 2aa71ab63b4457324c53700ab38ed83c3ccf7d5e Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Tue, 30 Apr 2019 10:23:47 +0100 Subject: [PATCH 1/4] tests: Rearrange assertions in the g_queue_clear_full() test This makes it a bit clearer that we expect the queue to be empty as a result of calling g_queue_clear_full(), rather than as a result of any of the later cleanup. Signed-off-by: Philip Withnall --- glib/tests/queue.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/glib/tests/queue.c b/glib/tests/queue.c index b2faeb14a..f9e9281fb 100644 --- a/glib/tests/queue.c +++ b/glib/tests/queue.c @@ -1083,15 +1083,13 @@ test_clear_full (void) g_assert_true (three->freed); g_assert_true (four->freed); + g_assert_true (g_queue_is_empty (queue)); check_integrity (queue); g_slice_free (QueueItem, one); g_slice_free (QueueItem, two); g_slice_free (QueueItem, three); g_slice_free (QueueItem, four); - - g_assert_true (g_queue_is_empty (queue)); - g_queue_free (queue); } From f033948998c63993bc57743b4189a3b58bc1e782 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Tue, 30 Apr 2019 10:24:37 +0100 Subject: [PATCH 2/4] tests: Add a test for calling g_queue_clear_full() with a NULL free_func This improves the branch coverage of gqueue.c a little. Signed-off-by: Philip Withnall --- glib/tests/queue.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/glib/tests/queue.c b/glib/tests/queue.c index f9e9281fb..7b2bb8749 100644 --- a/glib/tests/queue.c +++ b/glib/tests/queue.c @@ -1093,6 +1093,38 @@ test_clear_full (void) g_queue_free (queue); } +/* Check that g_queue_clear_full() called with a NULL free_func is equivalent + * to g_queue_clear(). */ +static void +test_clear_full_noop (void) +{ + QueueItem *one, *two, *three, *four; + GQueue *queue; + + queue = g_queue_new (); + g_queue_push_tail (queue, one = new_item (1)); + g_queue_push_tail (queue, two = new_item (2)); + g_queue_push_tail (queue, three = new_item (3)); + g_queue_push_tail (queue, four = new_item (4)); + + g_assert_cmpint (g_queue_get_length (queue), ==, 4); + g_assert_false (one->freed); + g_assert_false (two->freed); + g_assert_false (three->freed); + g_assert_false (four->freed); + + g_queue_clear_full (queue, NULL); + + g_assert_true (g_queue_is_empty (queue)); + check_integrity (queue); + + g_slice_free (QueueItem, one); + g_slice_free (QueueItem, two); + g_slice_free (QueueItem, three); + g_slice_free (QueueItem, four); + g_queue_free (queue); +} + static void test_free_full (void) { @@ -1165,6 +1197,7 @@ int main (int argc, char *argv[]) g_test_add_func ("/queue/clear", test_clear); g_test_add_func ("/queue/free-full", test_free_full); g_test_add_func ("/queue/clear-full", test_clear_full); + g_test_add_func ("/queue/clear-full/noop", test_clear_full_noop); g_test_add_func ("/queue/insert-sibling-link", test_insert_sibling_link); seed = g_test_rand_int_range (0, G_MAXINT); From 4f38620b134a40ed5b375e3b3908115447357a42 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Tue, 30 Apr 2019 10:37:37 +0100 Subject: [PATCH 3/4] tests: Add unit tests for g_queue_push_nth_link() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This should get its branch coverage up to 100%. For completeness’ sake. Signed-off-by: Philip Withnall --- glib/tests/queue.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/glib/tests/queue.c b/glib/tests/queue.c index 7b2bb8749..dd9dd2127 100644 --- a/glib/tests/queue.c +++ b/glib/tests/queue.c @@ -1125,6 +1125,94 @@ test_clear_full_noop (void) g_queue_free (queue); } +/* Test g_queue_push_nth_link() with various combinations of position (before, + * in the middle of, or at the end of the queue) and various existing queues + * (empty, single element, multiple elements). */ +static void +test_push_nth_link (void) +{ + GQueue *q; + q = g_queue_new (); + + /* Push onto before the front of an empty queue (which results in it being + * added to the end of the queue). */ + g_queue_push_nth_link (q, -1, g_list_prepend (NULL, GINT_TO_POINTER (1))); + check_integrity (q); + g_assert_cmpint (g_queue_get_length (q), ==, 1); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 0)), ==, 1); + + g_queue_clear (q); + + /* Push onto after the rear of an empty queue. */ + g_queue_push_nth_link (q, 100, g_list_prepend (NULL, GINT_TO_POINTER (2))); + check_integrity (q); + g_assert_cmpint (g_queue_get_length (q), ==, 1); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 0)), ==, 2); + + g_queue_clear (q); + + /* Push onto the front of an empty queue. */ + g_queue_push_nth_link (q, 0, g_list_prepend (NULL, GINT_TO_POINTER (3))); + check_integrity (q); + g_assert_cmpint (g_queue_get_length (q), ==, 1); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 0)), ==, 3); + + g_queue_clear (q); + + /* Push onto before the front of a non-empty queue (which results in it being + * added to the end of the queue). */ + g_queue_push_head (q, GINT_TO_POINTER (4)); + g_queue_push_nth_link (q, -1, g_list_prepend (NULL, GINT_TO_POINTER (5))); + check_integrity (q); + g_assert_cmpint (g_queue_get_length (q), ==, 2); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 0)), ==, 4); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 1)), ==, 5); + + g_queue_clear (q); + + /* Push onto after the rear of a non-empty queue. */ + g_queue_push_head (q, GINT_TO_POINTER (6)); + g_queue_push_nth_link (q, 100, g_list_prepend (NULL, GINT_TO_POINTER (7))); + check_integrity (q); + g_assert_cmpint (g_queue_get_length (q), ==, 2); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 0)), ==, 6); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 1)), ==, 7); + + g_queue_clear (q); + + /* Push onto the rear of a non-empty queue. */ + g_queue_push_head (q, GINT_TO_POINTER (8)); + g_queue_push_nth_link (q, 1, g_list_prepend (NULL, GINT_TO_POINTER (9))); + check_integrity (q); + g_assert_cmpint (g_queue_get_length (q), ==, 2); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 0)), ==, 8); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 1)), ==, 9); + + g_queue_clear (q); + + /* Push onto the front of a non-empty queue. */ + g_queue_push_head (q, GINT_TO_POINTER (10)); + g_queue_push_nth_link (q, 0, g_list_prepend (NULL, GINT_TO_POINTER (11))); + check_integrity (q); + g_assert_cmpint (g_queue_get_length (q), ==, 2); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 0)), ==, 11); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 1)), ==, 10); + + g_queue_clear (q); + + /* Push into the middle of a non-empty queue. */ + g_queue_push_head (q, GINT_TO_POINTER (12)); + g_queue_push_head (q, GINT_TO_POINTER (13)); + g_queue_push_nth_link (q, 1, g_list_prepend (NULL, GINT_TO_POINTER (14))); + check_integrity (q); + g_assert_cmpint (g_queue_get_length (q), ==, 3); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 0)), ==, 13); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 1)), ==, 14); + g_assert_cmpint (GPOINTER_TO_INT (g_queue_peek_nth (q, 2)), ==, 12); + + g_queue_free (q); +} + static void test_free_full (void) { @@ -1199,6 +1287,7 @@ int main (int argc, char *argv[]) g_test_add_func ("/queue/clear-full", test_clear_full); g_test_add_func ("/queue/clear-full/noop", test_clear_full_noop); g_test_add_func ("/queue/insert-sibling-link", test_insert_sibling_link); + g_test_add_func ("/queue/push-nth-link", test_push_nth_link); seed = g_test_rand_int_range (0, G_MAXINT); path = g_strdup_printf ("/queue/random/seed:%u", seed); From d5093350f3ea6a28bd02e4ed05466f83eacbd660 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Tue, 30 Apr 2019 11:01:20 +0100 Subject: [PATCH 4/4] gqueue: Remove a redundant branch queue->tail->next cannot be non-NULL, as pushing onto the end of the queue is handled by the call to g_queue_push_tail_link() above. Signed-off-by: Philip Withnall --- glib/gqueue.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/glib/gqueue.c b/glib/gqueue.c index e8c938a25..0cc7ab200 100644 --- a/glib/gqueue.c +++ b/glib/gqueue.c @@ -519,8 +519,10 @@ g_queue_push_nth_link (GQueue *queue, if (queue->head->prev) queue->head = queue->head->prev; - if (queue->tail->next) - queue->tail = queue->tail->next; + /* The case where we’re pushing @link_ at the end of @queue is handled above + * using g_queue_push_tail_link(), so we should never have to manually adjust + * queue->tail. */ + g_assert (queue->tail->next == NULL); queue->length++; }