gliststore: Improve the test coverage

https://bugzilla.gnome.org/show_bug.cgi?id=795307
This commit is contained in:
Christoph Reiter 2018-04-29 18:30:32 +02:00
parent 758d7073a9
commit fe9457dedd

View File

@ -318,6 +318,419 @@ test_store_splice_replace_all (void)
g_object_unref (store);
}
/* Test that using splice() without removing or adding anything works */
static void
test_store_splice_noop (void)
{
GListStore *store;
GListModel *model;
GAction *item;
store = g_list_store_new (G_TYPE_SIMPLE_ACTION);
model = G_LIST_MODEL (store);
/* splice noop with an empty list */
g_list_store_splice (store, 0, 0, NULL, 0);
g_assert_cmpuint (g_list_model_get_n_items (model), ==, 0);
/* splice noop with a non-empty list */
item = G_ACTION (g_simple_action_new ("1", NULL));
g_list_store_append (store, item);
g_object_unref (item);
g_list_store_splice (store, 0, 0, NULL, 0);
g_assert_cmpuint (g_list_model_get_n_items (model), ==, 1);
g_list_store_splice (store, 1, 0, NULL, 0);
g_assert_cmpuint (g_list_model_get_n_items (model), ==, 1);
item = g_list_model_get_item (model, 0);
g_assert_cmpstr (g_action_get_name (item), ==, "1");
g_object_unref (item);
g_object_unref (store);
}
static gboolean
model_array_equal (GListModel *model, GPtrArray *array)
{
guint i;
if (g_list_model_get_n_items (model) != array->len)
return FALSE;
for (i = 0; i < array->len; i++)
{
GObject *ptr;
gboolean ptrs_equal;
ptr = g_list_model_get_item (model, i);
ptrs_equal = (g_ptr_array_index (array, i) == ptr);
g_object_unref (ptr);
if (!ptrs_equal)
return FALSE;
}
return TRUE;
}
/* Test that using splice() to remove multiple items at different
* positions works */
static void
test_store_splice_remove_multiple (void)
{
GListStore *store;
GListModel *model;
GPtrArray *array;
store = g_list_store_new (G_TYPE_SIMPLE_ACTION);
model = G_LIST_MODEL (store);
array = g_ptr_array_new_full (0, g_object_unref);
g_ptr_array_add (array, g_simple_action_new ("1", NULL));
g_ptr_array_add (array, g_simple_action_new ("2", NULL));
g_ptr_array_add (array, g_simple_action_new ("3", NULL));
g_ptr_array_add (array, g_simple_action_new ("4", NULL));
g_ptr_array_add (array, g_simple_action_new ("5", NULL));
g_ptr_array_add (array, g_simple_action_new ("6", NULL));
g_ptr_array_add (array, g_simple_action_new ("7", NULL));
g_ptr_array_add (array, g_simple_action_new ("8", NULL));
g_ptr_array_add (array, g_simple_action_new ("9", NULL));
g_ptr_array_add (array, g_simple_action_new ("10", NULL));
/* Add all */
g_list_store_splice (store, 0, 0, array->pdata, array->len);
g_assert_true (model_array_equal (model, array));
/* Remove the first two */
g_list_store_splice (store, 0, 2, NULL, 0);
g_assert_false (model_array_equal (model, array));
g_ptr_array_remove_range (array, 0, 2);
g_assert_true (model_array_equal (model, array));
g_assert_cmpuint (g_list_model_get_n_items (model), ==, 8);
/* Remove two in the middle */
g_list_store_splice (store, 2, 2, NULL, 0);
g_assert_false (model_array_equal (model, array));
g_ptr_array_remove_range (array, 2, 2);
g_assert_true (model_array_equal (model, array));
g_assert_cmpuint (g_list_model_get_n_items (model), ==, 6);
/* Remove two at the end */
g_list_store_splice (store, 4, 2, NULL, 0);
g_assert_false (model_array_equal (model, array));
g_ptr_array_remove_range (array, 4, 2);
g_assert_true (model_array_equal (model, array));
g_assert_cmpuint (g_list_model_get_n_items (model), ==, 4);
g_ptr_array_unref (array);
g_object_unref (store);
}
/* Test that using splice() to add multiple items at different
* positions works */
static void
test_store_splice_add_multiple (void)
{
GListStore *store;
GListModel *model;
GPtrArray *array;
store = g_list_store_new (G_TYPE_SIMPLE_ACTION);
model = G_LIST_MODEL (store);
array = g_ptr_array_new_full (0, g_object_unref);
g_ptr_array_add (array, g_simple_action_new ("1", NULL));
g_ptr_array_add (array, g_simple_action_new ("2", NULL));
g_ptr_array_add (array, g_simple_action_new ("3", NULL));
g_ptr_array_add (array, g_simple_action_new ("4", NULL));
g_ptr_array_add (array, g_simple_action_new ("5", NULL));
g_ptr_array_add (array, g_simple_action_new ("6", NULL));
/* Add two at the beginning */
g_list_store_splice (store, 0, 0, array->pdata, 2);
/* Add two at the end */
g_list_store_splice (store, 2, 0, array->pdata + 4, 2);
/* Add two in the middle */
g_list_store_splice (store, 2, 0, array->pdata + 2, 2);
g_assert_true (model_array_equal (model, array));
g_ptr_array_unref (array);
g_object_unref (store);
}
/* Test that get_item_type() returns the right type */
static void
test_store_item_type (void)
{
GListStore *store;
GType gtype;
store = g_list_store_new (G_TYPE_SIMPLE_ACTION);
gtype = g_list_model_get_item_type (G_LIST_MODEL (store));
g_assert (gtype == G_TYPE_SIMPLE_ACTION);
g_object_unref (store);
}
/* Test that remove_all() removes all items */
static void
test_store_remove_all (void)
{
GListStore *store;
GListModel *model;
GSimpleAction *item;
store = g_list_store_new (G_TYPE_SIMPLE_ACTION);
model = G_LIST_MODEL (store);
/* Test with an empty list */
g_list_store_remove_all (store);
g_assert_cmpuint (g_list_model_get_n_items (model), ==, 0);
/* Test with a non-empty list */
item = g_simple_action_new ("42", NULL);
g_list_store_append (store, item);
g_list_store_append (store, item);
g_object_unref (item);
g_assert_cmpuint (g_list_model_get_n_items (model), ==, 2);
g_list_store_remove_all (store);
g_assert_cmpuint (g_list_model_get_n_items (model), ==, 0);
g_object_unref (store);
}
/* Test that splice() logs an error when passed the wrong item type */
static void
test_store_splice_wrong_type (void)
{
GListStore *store;
store = g_list_store_new (G_TYPE_SIMPLE_ACTION);
g_test_expect_message (G_LOG_DOMAIN,
G_LOG_LEVEL_CRITICAL,
"*GListStore instead of a GSimpleAction*");
g_list_store_splice (store, 0, 0, (gpointer)&store, 1);
g_object_unref (store);
}
static gint
ptr_array_cmp_action_by_name (GAction **a, GAction **b)
{
return g_strcmp0 (g_action_get_name (*a), g_action_get_name (*b));
}
static gint
list_model_cmp_action_by_name (GAction *a, GAction *b, gpointer user_data)
{
return g_strcmp0 (g_action_get_name (a), g_action_get_name (b));
}
/* Test if sort() works */
static void
test_store_sort (void)
{
GListStore *store;
GListModel *model;
GPtrArray *array;
store = g_list_store_new (G_TYPE_SIMPLE_ACTION);
model = G_LIST_MODEL (store);
array = g_ptr_array_new_full (0, g_object_unref);
g_ptr_array_add (array, g_simple_action_new ("2", NULL));
g_ptr_array_add (array, g_simple_action_new ("3", NULL));
g_ptr_array_add (array, g_simple_action_new ("9", NULL));
g_ptr_array_add (array, g_simple_action_new ("4", NULL));
g_ptr_array_add (array, g_simple_action_new ("5", NULL));
g_ptr_array_add (array, g_simple_action_new ("8", NULL));
g_ptr_array_add (array, g_simple_action_new ("6", NULL));
g_ptr_array_add (array, g_simple_action_new ("7", NULL));
g_ptr_array_add (array, g_simple_action_new ("1", NULL));
/* Sort an empty list */
g_list_store_sort (store, (GCompareDataFunc)list_model_cmp_action_by_name, NULL);
/* Add all */
g_list_store_splice (store, 0, 0, array->pdata, array->len);
g_assert_true (model_array_equal (model, array));
/* Sort both and check if the result is the same */
g_ptr_array_sort (array, (GCompareFunc)ptr_array_cmp_action_by_name);
g_assert_false (model_array_equal (model, array));
g_list_store_sort (store, (GCompareDataFunc)list_model_cmp_action_by_name, NULL);
g_assert_true (model_array_equal (model, array));
g_ptr_array_unref (array);
g_object_unref (store);
}
/* Test the cases where the item store tries to speed up item access by caching
* the last iter/position */
static void
test_store_get_item_cache (void)
{
GListStore *store;
GListModel *model;
GSimpleAction *item1, *item2, *temp;
store = g_list_store_new (G_TYPE_SIMPLE_ACTION);
model = G_LIST_MODEL (store);
/* Add two */
item1 = g_simple_action_new ("1", NULL);
g_list_store_append (store, item1);
item2 = g_simple_action_new ("2", NULL);
g_list_store_append (store, item2);
/* Clear the cache */
g_assert_null (g_list_model_get_item (model, 42));
/* Access the same position twice */
temp = g_list_model_get_item (model, 1);
g_assert (temp == item2);
g_object_unref (temp);
temp = g_list_model_get_item (model, 1);
g_assert (temp == item2);
g_object_unref (temp);
g_assert_null (g_list_model_get_item (model, 42));
/* Access forwards */
temp = g_list_model_get_item (model, 0);
g_assert (temp == item1);
g_object_unref (temp);
temp = g_list_model_get_item (model, 1);
g_assert (temp == item2);
g_object_unref (temp);
g_assert_null (g_list_model_get_item (model, 42));
/* Access backwards */
temp = g_list_model_get_item (model, 1);
g_assert (temp == item2);
g_object_unref (temp);
temp = g_list_model_get_item (model, 0);
g_assert (temp == item1);
g_object_unref (temp);
g_object_unref (item1);
g_object_unref (item2);
g_object_unref (store);
}
struct ItemsChangedData
{
guint position;
guint removed;
guint added;
gboolean called;
};
static void
expect_items_changed (struct ItemsChangedData *expected,
guint position,
guint removed,
guint added)
{
expected->position = position;
expected->removed = removed;
expected->added = added;
expected->called = FALSE;
}
static void
on_items_changed (GListModel *model,
guint position,
guint removed,
guint added,
struct ItemsChangedData *expected)
{
g_assert_false (expected->called);
g_assert_cmpuint (expected->position, ==, position);
g_assert_cmpuint (expected->removed, ==, removed);
g_assert_cmpuint (expected->added, ==, added);
expected->called = TRUE;
}
/* Test that all operations on the list emit the items-changed signal */
static void
test_store_signal_items_changed (void)
{
GListStore *store;
GListModel *model;
GSimpleAction *item;
struct ItemsChangedData expected = {0};
store = g_list_store_new (G_TYPE_SIMPLE_ACTION);
model = G_LIST_MODEL (store);
g_object_connect (model, "signal::items-changed",
on_items_changed, &expected, NULL);
/* Emit the signal manually */
expect_items_changed (&expected, 0, 0, 0);
g_list_model_items_changed (model, 0, 0, 0);
g_assert_true (expected.called);
/* Append an item */
expect_items_changed (&expected, 0, 0, 1);
item = g_simple_action_new ("2", NULL);
g_list_store_append (store, item);
g_object_unref (item);
g_assert_true (expected.called);
/* Insert an item */
expect_items_changed (&expected, 1, 0, 1);
item = g_simple_action_new ("1", NULL);
g_list_store_insert (store, 1, item);
g_object_unref (item);
g_assert_true (expected.called);
/* Sort the list */
expect_items_changed (&expected, 0, 2, 2);
g_list_store_sort (store,
(GCompareDataFunc)list_model_cmp_action_by_name,
NULL);
g_assert_true (expected.called);
/* Insert sorted */
expect_items_changed (&expected, 2, 0, 1);
item = g_simple_action_new ("3", NULL);
g_list_store_insert_sorted (store,
item,
(GCompareDataFunc)list_model_cmp_action_by_name,
NULL);
g_object_unref (item);
g_assert_true (expected.called);
/* Remove an item */
expect_items_changed (&expected, 1, 1, 0);
g_list_store_remove (store, 1);
g_assert_true (expected.called);
/* Splice */
expect_items_changed (&expected, 0, 2, 1);
item = g_simple_action_new ("4", NULL);
g_assert_cmpuint (g_list_model_get_n_items (model), >=, 2);
g_list_store_splice (store, 0, 2, (gpointer)&item, 1);
g_object_unref (item);
g_assert_true (expected.called);
/* Remove all */
expect_items_changed (&expected, 0, 1, 0);
g_assert_cmpuint (g_list_model_get_n_items (model), ==, 1);
g_list_store_remove_all (store);
g_assert_true (expected.called);
g_object_unref (store);
}
int main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
@ -330,6 +743,23 @@ int main (int argc, char *argv[])
test_store_splice_replace_middle);
g_test_add_func ("/glistmodel/store/splice-replace-all",
test_store_splice_replace_all);
g_test_add_func ("/glistmodel/store/splice-noop", test_store_splice_noop);
g_test_add_func ("/glistmodel/store/splice-remove-multiple",
test_store_splice_remove_multiple);
g_test_add_func ("/glistmodel/store/splice-add-multiple",
test_store_splice_add_multiple);
g_test_add_func ("/glistmodel/store/splice-wrong-type",
test_store_splice_wrong_type);
g_test_add_func ("/glistmodel/store/item-type",
test_store_item_type);
g_test_add_func ("/glistmodel/store/remove-all",
test_store_remove_all);
g_test_add_func ("/glistmodel/store/sort",
test_store_sort);
g_test_add_func ("/glistmodel/store/get-item-cache",
test_store_get_item_cache);
g_test_add_func ("/glistmodel/store/items-changed",
test_store_signal_items_changed);
return g_test_run ();
}