/*
 * Copyright 2015 Lars Uebernickel
 *
 * 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.1 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 <http://www.gnu.org/licenses/>.
 *
 * Authors: Lars Uebernickel <lars@uebernic.de>
 */

#include <gio/gio.h>

#include <string.h>

/* Wrapper around g_list_model_get_item() and g_list_model_get_object() which
 * checks they return the same thing. */
static gpointer
list_model_get (GListModel *model,
                guint       position)
{
  GObject *item = g_list_model_get_item (model, position);
  GObject *object = g_list_model_get_object (model, position);

  g_assert_true (item == object);

  g_clear_object (&object);
  return g_steal_pointer (&item);
}

/* Test that constructing/getting/setting properties on a #GListStore works. */
static void
test_store_properties (void)
{
  GListStore *store = NULL;
  GType item_type;

  store = g_list_store_new (G_TYPE_MENU_ITEM);
  g_object_get (store, "item-type", &item_type, NULL);
  g_assert_cmpint (item_type, ==, G_TYPE_MENU_ITEM);

  g_clear_object (&store);
}

/* Test that #GListStore rejects non-GObject item types. */
static void
test_store_non_gobjects (void)
{
  if (g_test_subprocess ())
    {
      /* We have to use g_object_new() since g_list_store_new() checks the item
       * type. We want to check the property setter code works properly. */
      g_object_new (G_TYPE_LIST_STORE, "item-type", G_TYPE_LONG, NULL);
      return;
    }

  g_test_trap_subprocess (NULL, 0, 0);
  g_test_trap_assert_failed ();
  g_test_trap_assert_stderr ("*WARNING*value * of type 'GType' is invalid or "
                             "out of range for property 'item-type'*");
}

static void
test_store_boundaries (void)
{
  GListStore *store;
  GMenuItem *item;

  store = g_list_store_new (G_TYPE_MENU_ITEM);

  item = g_menu_item_new (NULL, NULL);

  /* remove an item from an empty list */
  g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "*g_sequence*");
  g_list_store_remove (store, 0);
  g_test_assert_expected_messages ();

  /* don't allow inserting an item past the end ... */
  g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "*g_sequence*");
  g_list_store_insert (store, 1, item);
  g_assert_cmpuint (g_list_model_get_n_items (G_LIST_MODEL (store)), ==, 0);
  g_test_assert_expected_messages ();

  /* ... except exactly at the end */
  g_list_store_insert (store, 0, item);
  g_assert_cmpuint (g_list_model_get_n_items (G_LIST_MODEL (store)), ==, 1);

  /* remove a non-existing item at exactly the end of the list */
  g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "*g_sequence*");
  g_list_store_remove (store, 1);
  g_test_assert_expected_messages ();

  g_list_store_remove (store, 0);
  g_assert_cmpuint (g_list_model_get_n_items (G_LIST_MODEL (store)), ==, 0);

  /* splice beyond the end of the list */
  g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "*position*");
  g_list_store_splice (store, 1, 0, NULL, 0);
  g_test_assert_expected_messages ();

  /* remove items from an empty list */
  g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "*position*");
  g_list_store_splice (store, 0, 1, NULL, 0);
  g_test_assert_expected_messages ();

  g_list_store_append (store, item);
  g_list_store_splice (store, 0, 1, (gpointer *) &item, 1);
  g_assert_cmpuint (g_list_model_get_n_items (G_LIST_MODEL (store)), ==, 1);

  /* remove more items than exist */
  g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "*position*");
  g_list_store_splice (store, 0, 5, NULL, 0);
  g_test_assert_expected_messages ();
  g_assert_cmpuint (g_list_model_get_n_items (G_LIST_MODEL (store)), ==, 1);

  g_object_unref (store);
  g_assert_finalize_object (item);
}

static void
test_store_refcounts (void)
{
  GListStore *store;
  GMenuItem *items[10];
  GMenuItem *tmp;
  guint i;
  guint n_items;

  store = g_list_store_new (G_TYPE_MENU_ITEM);

  g_assert_cmpuint (g_list_model_get_n_items (G_LIST_MODEL (store)), ==, 0);
  g_assert_null (list_model_get (G_LIST_MODEL (store), 0));

  n_items = G_N_ELEMENTS (items);
  for (i = 0; i < n_items; i++)
    {
      items[i] = g_menu_item_new (NULL, NULL);
      g_object_add_weak_pointer (G_OBJECT (items[i]), (gpointer *) &items[i]);
      g_list_store_append (store, items[i]);

      g_object_unref (items[i]);
      g_assert_nonnull (items[i]);
    }

  g_assert_cmpuint (g_list_model_get_n_items (G_LIST_MODEL (store)), ==, n_items);
  g_assert_null (list_model_get (G_LIST_MODEL (store), n_items));

  tmp = list_model_get (G_LIST_MODEL (store), 3);
  g_assert_true (tmp == items[3]);
  g_object_unref (tmp);

  g_list_store_remove (store, 4);
  g_assert_null (items[4]);
  n_items--;
  g_assert_cmpuint (g_list_model_get_n_items (G_LIST_MODEL (store)), ==, n_items);
  g_assert_null (list_model_get (G_LIST_MODEL (store), n_items));

  g_object_unref (store);
  for (i = 0; i < G_N_ELEMENTS (items); i++)
    g_assert_null (items[i]);
}

static gchar *
make_random_string (void)
{
  gchar *str = g_malloc (10);
  gint i;

  for (i = 0; i < 9; i++)
    str[i] = g_test_rand_int_range ('a', 'z');
  str[i] = '\0';

  return str;
}

static gint
compare_items (gconstpointer a_p,
               gconstpointer b_p,
               gpointer      user_data)
{
  GObject *a_o = (GObject *) a_p;
  GObject *b_o = (GObject *) b_p;

  gchar *a = g_object_get_data (a_o, "key");
  gchar *b = g_object_get_data (b_o, "key");

  g_assert (user_data == GUINT_TO_POINTER(0x1234u));

  return strcmp (a, b);
}

static void
insert_string (GListStore  *store,
               const gchar *str)
{
  GObject *obj;

  obj = g_object_new (G_TYPE_OBJECT, NULL);
  g_object_set_data_full (obj, "key", g_strdup (str), g_free);

  g_list_store_insert_sorted (store, obj, compare_items, GUINT_TO_POINTER(0x1234u));

  g_object_unref (obj);
}

static void
test_store_sorted (void)
{
  GListStore *store;
  guint i;

  store = g_list_store_new (G_TYPE_OBJECT);

  for (i = 0; i < 1000; i++)
    {
      gchar *str = make_random_string ();
      insert_string (store, str);
      insert_string (store, str); /* multiple copies of the same are OK */
      g_free (str);
    }

  g_assert_cmpint (g_list_model_get_n_items (G_LIST_MODEL (store)), ==, 2000);

  for (i = 0; i < 1000; i++)
    {
      GObject *a, *b;

      /* should see our two copies */
      a = list_model_get (G_LIST_MODEL (store), i * 2);
      b = list_model_get (G_LIST_MODEL (store), i * 2 + 1);

      g_assert (compare_items (a, b, GUINT_TO_POINTER(0x1234)) == 0);
      g_assert (a != b);

      if (i)
        {
          GObject *c;

          c = list_model_get (G_LIST_MODEL (store), i * 2 - 1);
          g_assert (c != a);
          g_assert (c != b);

          g_assert (compare_items (b, c, GUINT_TO_POINTER(0x1234)) > 0);
          g_assert (compare_items (a, c, GUINT_TO_POINTER(0x1234)) > 0);

          g_object_unref (c);
        }

      g_object_unref (a);
      g_object_unref (b);
    }

  g_object_unref (store);
}

/* Test that using splice() to replace the middle element in a list store works. */
static void
test_store_splice_replace_middle (void)
{
  GListStore *store;
  GListModel *model;
  GAction *item;
  GPtrArray *array;

  g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=795307");

  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));

  /* Add three items through splice */
  g_list_store_splice (store, 0, 0, array->pdata, 3);
  g_assert_cmpuint (g_list_model_get_n_items (model), ==, 3);

  item = list_model_get (model, 0);
  g_assert_cmpstr (g_action_get_name (item), ==, "1");
  g_object_unref (item);
  item = list_model_get (model, 1);
  g_assert_cmpstr (g_action_get_name (item), ==, "2");
  g_object_unref (item);
  item = list_model_get (model, 2);
  g_assert_cmpstr (g_action_get_name (item), ==, "3");
  g_object_unref (item);

  /* Replace the middle one with two new items */
  g_list_store_splice (store, 1, 1, array->pdata + 3, 2);
  g_assert_cmpuint (g_list_model_get_n_items (model), ==, 4);

  item = list_model_get (model, 0);
  g_assert_cmpstr (g_action_get_name (item), ==, "1");
  g_object_unref (item);
  item = list_model_get (model, 1);
  g_assert_cmpstr (g_action_get_name (item), ==, "4");
  g_object_unref (item);
  item = list_model_get (model, 2);
  g_assert_cmpstr (g_action_get_name (item), ==, "5");
  g_object_unref (item);
  item = list_model_get (model, 3);
  g_assert_cmpstr (g_action_get_name (item), ==, "3");
  g_object_unref (item);

  g_ptr_array_unref (array);
  g_object_unref (store);
}

/* Test that using splice() to replace the whole list store works. */
static void
test_store_splice_replace_all (void)
{
  GListStore *store;
  GListModel *model;
  GPtrArray *array;
  GAction *item;

  g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=795307");

  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));

  /* Add the first two */
  g_list_store_splice (store, 0, 0, array->pdata, 2);

  g_assert_cmpuint (g_list_model_get_n_items (model), ==, 2);
  item = list_model_get (model, 0);
  g_assert_cmpstr (g_action_get_name (item), ==, "1");
  g_object_unref (item);
  item = list_model_get (model, 1);
  g_assert_cmpstr (g_action_get_name (item), ==, "2");
  g_object_unref (item);

  /* Replace all with the last two */
  g_list_store_splice (store, 0, 2, array->pdata + 2, 2);

  g_assert_cmpuint (g_list_model_get_n_items (model), ==, 2);
  item = list_model_get (model, 0);
  g_assert_cmpstr (g_action_get_name (item), ==, "3");
  g_object_unref (item);
  item = list_model_get (model, 1);
  g_assert_cmpstr (g_action_get_name (item), ==, "4");
  g_object_unref (item);

  g_ptr_array_unref (array);
  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 = list_model_get (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 = list_model_get (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 (list_model_get (model, 42));

  /* Access the same position twice */
  temp = list_model_get (model, 1);
  g_assert (temp == item2);
  g_object_unref (temp);
  temp = list_model_get (model, 1);
  g_assert (temp == item2);
  g_object_unref (temp);

  g_assert_null (list_model_get (model, 42));

  /* Access forwards */
  temp = list_model_get (model, 0);
  g_assert (temp == item1);
  g_object_unref (temp);
  temp = list_model_get (model, 1);
  g_assert (temp == item2);
  g_object_unref (temp);

  g_assert_null (list_model_get (model, 42));

  /* Access backwards */
  temp = list_model_get (model, 1);
  g_assert (temp == item2);
  g_object_unref (temp);
  temp = list_model_get (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);
}

/* Due to an overflow in the list store last-iter optimization,
 * the sequence 'lookup 0; lookup MAXUINT' was returning the
 * same item twice, and not NULL for the second lookup.
 * See #1639.
 */
static void
test_store_past_end (void)
{
  GListStore *store;
  GListModel *model;
  GSimpleAction *item;

  store = g_list_store_new (G_TYPE_SIMPLE_ACTION);
  model = G_LIST_MODEL (store);

  item = g_simple_action_new ("2", NULL);
  g_list_store_append (store, item);
  g_object_unref (item);

  g_assert_cmpint (g_list_model_get_n_items (model), ==, 1);
  item = g_list_model_get_item (model, 0);
  g_assert_nonnull (item);
  g_object_unref (item);
  item = g_list_model_get_item (model, G_MAXUINT);
  g_assert_null (item);

  g_object_unref (store);
}

static gboolean
list_model_casecmp_action_by_name (gconstpointer a,
                                   gconstpointer b)
{
  return g_ascii_strcasecmp (g_action_get_name (G_ACTION (a)),
                             g_action_get_name (G_ACTION (b))) == 0;
}

/* Test if find() and find_with_equal_func() works */
static void
test_store_find (void)
{
  GListStore *store;
  guint position = 100;
  const gchar *item_strs[4] = { "aaa", "bbb", "xxx", "ccc" };
  GSimpleAction *items[4] = { NULL, };
  GSimpleAction *other_item;
  guint i;

  store = g_list_store_new (G_TYPE_SIMPLE_ACTION);

  for (i = 0; i < G_N_ELEMENTS (item_strs); i++)
    items[i] = g_simple_action_new (item_strs[i], NULL);

  /* Shouldn't crash on an empty list, or change the position pointer */
  g_assert_false (g_list_store_find (store, items[0], NULL));
  g_assert_false (g_list_store_find (store, items[0], &position));
  g_assert_cmpint (position, ==, 100);

  for (i = 0; i < G_N_ELEMENTS (item_strs); i++)
    g_list_store_append (store, items[i]);

  /* Check whether it could still find the the elements */
  for (i = 0; i < G_N_ELEMENTS (item_strs); i++)
    {
      g_assert_true (g_list_store_find (store, items[i], &position));
      g_assert_cmpint (position, ==, i);
      /* Shouldn't try to write to position pointer if NULL given */
      g_assert_true (g_list_store_find (store, items[i], NULL));
    }

  /* try to find element not part of the list */
  other_item = g_simple_action_new ("111", NULL);
  g_assert_false (g_list_store_find (store, other_item, NULL));
  g_clear_object (&other_item);

  /* Re-add item; find() should only return the first position */
  g_list_store_append (store, items[0]);
  g_assert_true (g_list_store_find (store, items[0], &position));
  g_assert_cmpint (position, ==, 0);

  /* try to find element which should only work with custom equality check */
  other_item = g_simple_action_new ("XXX", NULL);
  g_assert_false (g_list_store_find (store, other_item, NULL));
  g_assert_true (g_list_store_find_with_equal_func (store,
                                                    other_item,
                                                    list_model_casecmp_action_by_name,
                                                    &position));
  g_assert_cmpint (position, ==, 2);
  g_clear_object (&other_item);

  for (i = 0; i < G_N_ELEMENTS (item_strs); i++)
    g_clear_object(&items[i]);
  g_clear_object (&store);
}

int main (int argc, char *argv[])
{
  g_test_init (&argc, &argv, NULL);

  g_test_add_func ("/glistmodel/store/properties", test_store_properties);
  g_test_add_func ("/glistmodel/store/non-gobjects", test_store_non_gobjects);
  g_test_add_func ("/glistmodel/store/boundaries", test_store_boundaries);
  g_test_add_func ("/glistmodel/store/refcounts", test_store_refcounts);
  g_test_add_func ("/glistmodel/store/sorted", test_store_sorted);
  g_test_add_func ("/glistmodel/store/splice-replace-middle",
                   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);
  g_test_add_func ("/glistmodel/store/past-end", test_store_past_end);
  g_test_add_func ("/glistmodel/store/find", test_store_find);

  return g_test_run ();
}
