[gtk+] Have the unit test check if the filter model emits the right signals
- From: Kristian Rietveld <kristian src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gtk+] Have the unit test check if the filter model emits the right signals
- Date: Sat, 5 Sep 2009 15:26:58 +0000 (UTC)
commit bf573a1e1ef913e309ffcab1feb4bc5ee8da1a3d
Author: Kristian Rietveld <kris gtk org>
Date: Sat Sep 5 15:57:25 2009 +0200
Have the unit test check if the filter model emits the right signals
gtk/tests/filtermodel.c | 612 ++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 610 insertions(+), 2 deletions(-)
---
diff --git a/gtk/tests/filtermodel.c b/gtk/tests/filtermodel.c
index 77f7231..52e0d51 100644
--- a/gtk/tests/filtermodel.c
+++ b/gtk/tests/filtermodel.c
@@ -74,6 +74,218 @@ create_tree_store (int depth,
return store;
}
+/*
+ * Signal monitor
+ */
+
+typedef enum
+{
+ ROW_INSERTED,
+ ROW_DELETED,
+ ROW_CHANGED,
+ ROW_HAS_CHILD_TOGGLED,
+ ROWS_REORDERED,
+ LAST_SIGNAL
+}
+SignalName;
+
+typedef struct
+{
+ SignalName signal;
+ GtkTreePath *path;
+}
+Signal;
+
+
+static Signal *
+signal_new (SignalName signal, GtkTreePath *path)
+{
+ Signal *s;
+
+ s = g_new0 (Signal, 1);
+ s->signal = signal;
+ s->path = gtk_tree_path_copy (path);
+
+ return s;
+}
+
+static void
+signal_free (Signal *s)
+{
+ if (s->path)
+ gtk_tree_path_free (s->path);
+
+ g_free (s);
+}
+
+
+typedef struct
+{
+ GQueue *queue;
+ GtkTreeModel *client;
+ guint signal_ids[LAST_SIGNAL];
+}
+SignalMonitor;
+
+
+static void
+signal_monitor_generic_handler (SignalMonitor *m,
+ SignalName signal,
+ GtkTreeModel *model,
+ GtkTreePath *path)
+{
+ Signal *s;
+
+ g_return_if_fail (m->client == model);
+ g_return_if_fail (!g_queue_is_empty (m->queue));
+
+#if 0
+ /* For debugging: output signals that are coming in. Leaks memory. */
+ g_print ("signal=%d path=%s\n", signal, gtk_tree_path_to_string (path));
+#endif
+
+ s = g_queue_peek_tail (m->queue);
+
+ g_return_if_fail (s->signal == signal);
+
+ s = g_queue_pop_tail (m->queue);
+
+ g_return_if_fail (!gtk_tree_path_compare (path, s->path));
+
+ signal_free (s);
+}
+
+static void
+signal_monitor_row_inserted (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ signal_monitor_generic_handler (data, ROW_INSERTED,
+ model, path);
+}
+
+static void
+signal_monitor_row_deleted (GtkTreeModel *model,
+ GtkTreePath *path,
+ gpointer data)
+{
+ signal_monitor_generic_handler (data, ROW_DELETED,
+ model, path);
+}
+
+static void
+signal_monitor_row_changed (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ signal_monitor_generic_handler (data, ROW_CHANGED,
+ model, path);
+}
+
+static void
+signal_monitor_row_has_child_toggled (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ signal_monitor_generic_handler (data, ROW_HAS_CHILD_TOGGLED,
+ model, path);
+}
+
+static void
+signal_monitor_rows_reordered (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gint *new_order,
+ gpointer data)
+{
+ signal_monitor_generic_handler (data, ROWS_REORDERED,
+ model, path);
+}
+
+static SignalMonitor *
+signal_monitor_new (GtkTreeModel *client)
+{
+ SignalMonitor *m;
+
+ m = g_new0 (SignalMonitor, 1);
+ m->client = g_object_ref (client);
+ m->queue = g_queue_new ();
+
+ m->signal_ids[ROW_INSERTED] = g_signal_connect (client,
+ "row-inserted",
+ G_CALLBACK (signal_monitor_row_inserted),
+ m);
+ m->signal_ids[ROW_DELETED] = g_signal_connect (client,
+ "row-deleted",
+ G_CALLBACK (signal_monitor_row_deleted),
+ m);
+ m->signal_ids[ROW_CHANGED] = g_signal_connect (client,
+ "row-changed",
+ G_CALLBACK (signal_monitor_row_changed),
+ m);
+ m->signal_ids[ROW_HAS_CHILD_TOGGLED] = g_signal_connect (client,
+ "row-has-child-toggled",
+ G_CALLBACK (signal_monitor_row_has_child_toggled),
+ m);
+ m->signal_ids[ROWS_REORDERED] = g_signal_connect (client,
+ "rows-reordered",
+ G_CALLBACK (signal_monitor_rows_reordered),
+ m);
+
+ return m;
+}
+
+static void
+signal_monitor_free (SignalMonitor *m)
+{
+ int i;
+
+ for (i = 0; i < LAST_SIGNAL; i++)
+ g_signal_handler_disconnect (m->client, m->signal_ids[i]);
+
+ g_object_unref (m->client);
+
+ if (m->queue)
+ g_queue_free (m->queue);
+
+ g_free (m);
+}
+
+static void
+signal_monitor_assert_is_empty (SignalMonitor *m)
+{
+ g_assert (g_queue_is_empty (m->queue));
+}
+
+static void
+signal_monitor_append_signal_path (SignalMonitor *m,
+ SignalName signal,
+ GtkTreePath *path)
+{
+ Signal *s;
+
+ s = signal_new (signal, path);
+ g_queue_push_head (m->queue, s);
+}
+
+static void
+signal_monitor_append_signal (SignalMonitor *m,
+ SignalName signal,
+ const gchar *path_string)
+{
+ Signal *s;
+ GtkTreePath *path;
+
+ path = gtk_tree_path_new_from_string (path_string);
+
+ s = signal_new (signal, path);
+ g_queue_push_head (m->queue, s);
+
+ gtk_tree_path_free (path);
+}
/*
* Fixture
@@ -85,6 +297,8 @@ typedef struct
GtkTreeStore *store;
GtkTreeModelFilter *filter;
+
+ SignalMonitor *monitor;
} FilterTest;
static void
@@ -111,6 +325,8 @@ filter_test_setup_generic (FilterTest *fixture,
* side.
*/
fixture->tree_view = gtk_tree_view_new_with_model (filter);
+
+ fixture->monitor = signal_monitor_new (filter);
}
static void
@@ -141,6 +357,202 @@ filter_test_setup_empty_unfiltered (FilterTest *fixture,
filter_test_setup_generic (fixture, test_data, 3, TRUE, TRUE);
}
+static GtkTreePath *
+strip_virtual_root (GtkTreePath *path,
+ GtkTreePath *root_path)
+{
+ GtkTreePath *real_path;
+
+ if (root_path)
+ {
+ int j;
+ int depth = gtk_tree_path_get_depth (path);
+ int root_depth = gtk_tree_path_get_depth (root_path);
+
+ real_path = gtk_tree_path_new ();
+
+ for (j = 0; j < depth - root_depth; j++)
+ gtk_tree_path_append_index (real_path,
+ gtk_tree_path_get_indices (path)[root_depth + j]);
+ }
+ else
+ real_path = gtk_tree_path_copy (path);
+
+ return real_path;
+}
+
+static void
+filter_test_append_refilter_signals_recurse (FilterTest *fixture,
+ GtkTreePath *store_path,
+ GtkTreePath *filter_path,
+ int depth,
+ GtkTreePath *root_path)
+{
+ int i;
+ int rows_deleted = 0;
+ GtkTreeIter iter;
+
+ gtk_tree_path_down (store_path);
+ gtk_tree_path_down (filter_path);
+
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
+ &iter, store_path);
+
+ for (i = 0; i < LEVEL_LENGTH; i++)
+ {
+ gboolean visible;
+ GtkTreePath *real_path;
+
+ gtk_tree_model_get (GTK_TREE_MODEL (fixture->store), &iter,
+ 1, &visible,
+ -1);
+
+ if (root_path &&
+ (!gtk_tree_path_is_descendant (store_path, root_path)
+ || !gtk_tree_path_compare (store_path, root_path)))
+ {
+ if (!gtk_tree_path_compare (store_path, root_path))
+ {
+ if (depth > 1
+ && gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store),
+ &iter))
+ {
+ GtkTreePath *store_copy;
+ GtkTreePath *filter_copy;
+
+ store_copy = gtk_tree_path_copy (store_path);
+ filter_copy = gtk_tree_path_copy (filter_path);
+ filter_test_append_refilter_signals_recurse (fixture,
+ store_copy,
+ filter_copy,
+ depth - 1,
+ root_path);
+ gtk_tree_path_free (store_copy);
+ gtk_tree_path_free (filter_copy);
+ }
+ }
+
+ gtk_tree_path_next (store_path);
+ gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
+
+ if (visible)
+ gtk_tree_path_next (filter_path);
+
+ continue;
+ }
+
+ real_path = strip_virtual_root (filter_path, root_path);
+
+ if (visible)
+ {
+ /* This row will be inserted */
+ signal_monitor_append_signal_path (fixture->monitor, ROW_CHANGED,
+ real_path);
+ signal_monitor_append_signal_path (fixture->monitor,
+ ROW_HAS_CHILD_TOGGLED,
+ real_path);
+
+ if (depth > 1
+ && gtk_tree_model_iter_has_child (GTK_TREE_MODEL (fixture->store),
+ &iter))
+ {
+ GtkTreePath *store_copy;
+ GtkTreePath *filter_copy;
+
+ store_copy = gtk_tree_path_copy (store_path);
+ filter_copy = gtk_tree_path_copy (filter_path);
+ filter_test_append_refilter_signals_recurse (fixture,
+ store_copy,
+ filter_copy,
+ depth - 1,
+ root_path);
+ gtk_tree_path_free (store_copy);
+ gtk_tree_path_free (filter_copy);
+ }
+
+ gtk_tree_path_next (filter_path);
+ }
+ else
+ {
+ /* This row will be deleted */
+ rows_deleted++;
+ signal_monitor_append_signal_path (fixture->monitor, ROW_DELETED,
+ real_path);
+ }
+
+ gtk_tree_path_free (real_path);
+
+ gtk_tree_path_next (store_path);
+ gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store), &iter);
+ }
+
+ if (rows_deleted == LEVEL_LENGTH
+ && gtk_tree_path_get_depth (filter_path) > 1)
+ {
+ GtkTreePath *real_path;
+
+ gtk_tree_path_up (store_path);
+ gtk_tree_path_up (filter_path);
+
+ /* A row-has-child-toggled will be emitted on the parent */
+ if (!root_path
+ || (root_path
+ && gtk_tree_path_is_descendant (store_path, root_path)
+ && gtk_tree_path_compare (store_path, root_path)))
+ {
+ real_path = strip_virtual_root (filter_path, root_path);
+ signal_monitor_append_signal_path (fixture->monitor,
+ ROW_HAS_CHILD_TOGGLED,
+ real_path);
+
+ gtk_tree_path_free (real_path);
+ }
+ }
+}
+
+static void
+filter_test_append_refilter_signals (FilterTest *fixture,
+ int depth)
+{
+ /* A special function that walks the tree store like the
+ * model validation functions below.
+ */
+ GtkTreePath *path;
+ GtkTreePath *filter_path;
+
+ path = gtk_tree_path_new ();
+ filter_path = gtk_tree_path_new ();
+ filter_test_append_refilter_signals_recurse (fixture,
+ path,
+ filter_path,
+ depth,
+ NULL);
+ gtk_tree_path_free (path);
+ gtk_tree_path_free (filter_path);
+}
+
+static void
+filter_test_append_refilter_signals_with_vroot (FilterTest *fixture,
+ int depth,
+ GtkTreePath *root_path)
+{
+ /* A special function that walks the tree store like the
+ * model validation functions below.
+ */
+ GtkTreePath *path;
+ GtkTreePath *filter_path;
+
+ path = gtk_tree_path_new ();
+ filter_path = gtk_tree_path_new ();
+ filter_test_append_refilter_signals_recurse (fixture,
+ path,
+ filter_path,
+ depth,
+ root_path);
+ gtk_tree_path_free (path);
+ gtk_tree_path_free (filter_path);
+}
+
static void
filter_test_enable_filter (FilterTest *fixture)
{
@@ -152,6 +564,8 @@ static void
filter_test_teardown (FilterTest *fixture,
gconstpointer test_data)
{
+ signal_monitor_free (fixture->monitor);
+
g_object_unref (fixture->filter);
g_object_unref (fixture->store);
}
@@ -247,6 +661,9 @@ check_filter_model (FilterTest *fixture)
{
GtkTreePath *path;
+ if (fixture->monitor)
+ signal_monitor_assert_is_empty (fixture->monitor);
+
path = gtk_tree_path_new ();
check_filter_model_recurse (fixture, path, gtk_tree_path_copy (path));
@@ -256,6 +673,9 @@ static void
check_filter_model_with_root (FilterTest *fixture,
GtkTreePath *path)
{
+ if (fixture->monitor)
+ signal_monitor_assert_is_empty (fixture->monitor);
+
check_filter_model_recurse (fixture,
gtk_tree_path_copy (path),
gtk_tree_path_new ());
@@ -345,20 +765,26 @@ static void
filled_hide_root_level (FilterTest *fixture,
gconstpointer user_data)
{
+ signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
set_path_visibility (fixture, "2", FALSE);
check_filter_model (fixture);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
+ signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
set_path_visibility (fixture, "0", FALSE);
check_filter_model (fixture);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
+ signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
set_path_visibility (fixture, "4", FALSE);
check_filter_model (fixture);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 3);
/* Hide remaining */
+ signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
+ signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
+
set_path_visibility (fixture, "1", FALSE);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
@@ -368,6 +794,11 @@ filled_hide_root_level (FilterTest *fixture,
check_filter_model (fixture);
/* Show some */
+ signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
+ signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
+
set_path_visibility (fixture, "1", TRUE);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
@@ -381,11 +812,13 @@ static void
filled_hide_child_levels (FilterTest *fixture,
gconstpointer user_data)
{
+ signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:2");
set_path_visibility (fixture, "0:2", FALSE);
check_filter_model (fixture);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
+ signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:3");
set_path_visibility (fixture, "0:4", FALSE);
check_filter_model (fixture);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
@@ -404,19 +837,34 @@ filled_hide_child_levels (FilterTest *fixture,
check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
- set_path_visibility (fixture, "0:4", TRUE);
/* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
+ signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:3");
+ /* FIXME: Actually, the filter model should not be emitted the
+ * row-has-child-toggled signal here. *However* an extraneous emission
+ * of this signal does not hurt and is allowed.
+ */
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:3");
+ set_path_visibility (fixture, "0:4", TRUE);
check_filter_model (fixture);
check_level_length (fixture->filter, "0:3", 0);
+ signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:2");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:2");
set_path_visibility (fixture, "0:2", TRUE);
check_filter_model (fixture);
check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
check_level_length (fixture->filter, "0:4", 0);
+ /* FIXME: We are missing a row-has-child-toggled signal for path "0:4" */
+ signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:0");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4:0");
+ signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:1");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:4:1");
+
set_path_visibility (fixture, "0:4:2", TRUE);
set_path_visibility (fixture, "0:4:4", TRUE);
+ signal_monitor_assert_is_empty (fixture->monitor);
check_level_length (fixture->filter, "0:4", 2);
}
@@ -474,10 +922,12 @@ filled_vroot_hide_root_level (FilterTest *fixture,
check_filter_model_with_root (fixture, path);
/* Now test changes in the virtual root level */
+ signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "2");
set_path_visibility (fixture, "2:2", FALSE);
check_filter_model_with_root (fixture, path);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
+ signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "3");
set_path_visibility (fixture, "2:4", FALSE);
check_filter_model_with_root (fixture, path);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
@@ -486,6 +936,8 @@ filled_vroot_hide_root_level (FilterTest *fixture,
check_filter_model_with_root (fixture, path);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 2);
+ signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "3");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "3");
set_path_visibility (fixture, "2:4", TRUE);
check_filter_model_with_root (fixture, path);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
@@ -494,6 +946,10 @@ filled_vroot_hide_root_level (FilterTest *fixture,
check_filter_model_with_root (fixture, path);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 1);
+ signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
+ signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
+ signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
+ signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
set_path_visibility (fixture, "2:0", FALSE);
set_path_visibility (fixture, "2:1", FALSE);
set_path_visibility (fixture, "2:2", FALSE);
@@ -510,10 +966,13 @@ filled_vroot_hide_root_level (FilterTest *fixture,
check_filter_model_with_root (fixture, path);
check_level_length (fixture->filter, NULL, 0);
+ signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
set_path_visibility (fixture, "2:4", TRUE);
check_filter_model_with_root (fixture, path);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH - 4);
+ signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
set_path_visibility (fixture, "2:4", FALSE);
check_filter_model_with_root (fixture, path);
check_level_length (fixture->filter, NULL, 0);
@@ -522,6 +981,12 @@ filled_vroot_hide_root_level (FilterTest *fixture,
check_filter_model_with_root (fixture, path);
check_level_length (fixture->filter, NULL, 0);
+ signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
+ signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "1");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "1");
+ signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
set_path_visibility (fixture, "2:0", TRUE);
set_path_visibility (fixture, "2:1", TRUE);
set_path_visibility (fixture, "2:2", TRUE);
@@ -539,11 +1004,13 @@ filled_vroot_hide_child_levels (FilterTest *fixture,
{
GtkTreePath *path = (GtkTreePath *)user_data;
+ signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:2");
set_path_visibility (fixture, "2:0:2", FALSE);
check_filter_model_with_root (fixture, path);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
check_level_length (fixture->filter, "0", LEVEL_LENGTH - 1);
+ signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0:3");
set_path_visibility (fixture, "2:0:4", FALSE);
check_filter_model_with_root (fixture, path);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
@@ -562,17 +1029,31 @@ filled_vroot_hide_child_levels (FilterTest *fixture,
check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
check_level_length (fixture->filter, "0", LEVEL_LENGTH - 2);
- set_path_visibility (fixture, "2:0:4", TRUE);
/* Since "0:2" is hidden, "0:4" must be "0:3" in the filter model */
+ signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:3");
+ /* FIXME: Actually, the filter model should not be emitted the
+ * row-has-child-toggled signal here. *However* an extraneous emission
+ * of this signal does not hurt and is allowed.
+ */
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:3");
+ set_path_visibility (fixture, "2:0:4", TRUE);
check_filter_model_with_root (fixture, path);
check_level_length (fixture->filter, "0:3", 0);
+ signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:2");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:2");
set_path_visibility (fixture, "2:0:2", TRUE);
check_filter_model_with_root (fixture, path);
check_level_length (fixture->filter, "0:2", LEVEL_LENGTH);
check_level_length (fixture->filter, "0:3", LEVEL_LENGTH);
check_level_length (fixture->filter, "0:4", 0);
+ /* FIXME: We are missing a row-has-child-toggled signal for path "0:4" */
+ /* FIXME: Inconsistency! For the non-vroot case we also receive two
+ * row-has-child-toggled signals here.
+ */
+ signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:0");
+ signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:4:1");
set_path_visibility (fixture, "2:0:4:2", TRUE);
set_path_visibility (fixture, "2:0:4:4", TRUE);
check_level_length (fixture->filter, "0:4", 2);
@@ -586,6 +1067,8 @@ empty_show_nodes (FilterTest *fixture,
check_filter_model (fixture);
check_level_length (fixture->filter, NULL, 0);
+ signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
set_path_visibility (fixture, "3", TRUE);
check_filter_model (fixture);
check_level_length (fixture->filter, NULL, 1);
@@ -596,6 +1079,8 @@ empty_show_nodes (FilterTest *fixture,
check_level_length (fixture->filter, NULL, 1);
check_level_length (fixture->filter, "0", 0);
+ signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0:0");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0:0");
set_path_visibility (fixture, "3:2", TRUE);
check_filter_model (fixture);
check_level_length (fixture->filter, NULL, 1);
@@ -603,10 +1088,13 @@ empty_show_nodes (FilterTest *fixture,
check_level_length (fixture->filter, "0:0", 1);
check_level_length (fixture->filter, "0:0:0", 0);
+ signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
set_path_visibility (fixture, "3", FALSE);
check_filter_model (fixture);
check_level_length (fixture->filter, NULL, 0);
+ signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
set_path_visibility (fixture, "3:2:1", TRUE);
set_path_visibility (fixture, "3", TRUE);
check_filter_model (fixture);
@@ -633,6 +1121,8 @@ empty_vroot_show_nodes (FilterTest *fixture,
check_filter_model_with_root (fixture, path);
check_level_length (fixture->filter, NULL, 0);
+ signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
set_path_visibility (fixture, "2:2", TRUE);
check_filter_model_with_root (fixture, path);
check_level_length (fixture->filter, NULL, 1);
@@ -643,10 +1133,13 @@ empty_vroot_show_nodes (FilterTest *fixture,
check_filter_model_with_root (fixture, path);
check_level_length (fixture->filter, NULL, 1);
+ signal_monitor_append_signal (fixture->monitor, ROW_DELETED, "0");
set_path_visibility (fixture, "2:2", FALSE);
check_filter_model_with_root (fixture, path);
check_level_length (fixture->filter, NULL, 0);
+ signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
set_path_visibility (fixture, "2:2:1", TRUE);
set_path_visibility (fixture, "2:2", TRUE);
check_filter_model_with_root (fixture, path);
@@ -661,10 +1154,17 @@ unfiltered_hide_single (FilterTest *fixture,
gconstpointer user_data)
{
+ signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
set_path_visibility (fixture, "2", FALSE);
+ signal_monitor_assert_is_empty (fixture->monitor);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+ /* The view only shows the root level, so the filter model only has
+ * the first two levels cached.
+ */
+ filter_test_append_refilter_signals (fixture, 2);
filter_test_enable_filter (fixture);
check_filter_model (fixture);
@@ -676,11 +1176,18 @@ unfiltered_hide_single_child (FilterTest *fixture,
gconstpointer user_data)
{
+ signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
set_path_visibility (fixture, "2:2", FALSE);
+ signal_monitor_assert_is_empty (fixture->monitor);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
check_level_length (fixture->filter, "2", LEVEL_LENGTH);
+ /* The view only shows the root level, so the filter model only has
+ * the first two levels cached.
+ */
+ filter_test_append_refilter_signals (fixture, 2);
filter_test_enable_filter (fixture);
check_filter_model (fixture);
@@ -693,19 +1200,30 @@ unfiltered_hide_single_multi_level (FilterTest *fixture,
gconstpointer user_data)
{
+ /* This row is not shown, so its signal is not propagated */
set_path_visibility (fixture, "2:2:2", FALSE);
+
+ signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
set_path_visibility (fixture, "2:2", FALSE);
+ signal_monitor_assert_is_empty (fixture->monitor);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
check_level_length (fixture->filter, "2", LEVEL_LENGTH);
check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
+ /* The view only shows the root level, so the filter model only has
+ * the first two levels cached.
+ */
+ filter_test_append_refilter_signals (fixture, 2);
filter_test_enable_filter (fixture);
check_filter_model (fixture);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
+ signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2:2");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
set_path_visibility (fixture, "2:2", TRUE);
check_filter_model (fixture);
@@ -722,10 +1240,18 @@ unfiltered_vroot_hide_single (FilterTest *fixture,
{
GtkTreePath *path = (GtkTreePath *)user_data;
+ signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
set_path_visibility (fixture, "2:2", FALSE);
+ signal_monitor_assert_is_empty (fixture->monitor);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+ /* The view only shows the root level, so the filter model only has
+ * the first two levels cached. (We add an additional level to
+ * take the virtual root into account).
+ */
+ filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
filter_test_enable_filter (fixture);
check_filter_model_with_root (fixture, path);
@@ -739,11 +1265,19 @@ unfiltered_vroot_hide_single_child (FilterTest *fixture,
{
GtkTreePath *path = (GtkTreePath *)user_data;
+ signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
set_path_visibility (fixture, "2:2:2", FALSE);
+ signal_monitor_assert_is_empty (fixture->monitor);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
check_level_length (fixture->filter, "2", LEVEL_LENGTH);
+ /* The view only shows the root level, so the filter model only has
+ * the first two levels cached. (We add an additional level to take
+ * the virtual root into account).
+ */
+ filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
filter_test_enable_filter (fixture);
check_filter_model_with_root (fixture, path);
@@ -758,19 +1292,30 @@ unfiltered_vroot_hide_single_multi_level (FilterTest *fixture,
{
GtkTreePath *path = (GtkTreePath *)user_data;
+ /* This row is not shown, so its signal is not propagated */
set_path_visibility (fixture, "2:2:2:2", FALSE);
+
+ signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
set_path_visibility (fixture, "2:2:2", FALSE);
+ signal_monitor_assert_is_empty (fixture->monitor);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
check_level_length (fixture->filter, "2", LEVEL_LENGTH);
check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
+ /* The view only shows the root level, so the filter model only has
+ * the first two levels cached.
+ */
+ filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
filter_test_enable_filter (fixture);
check_filter_model_with_root (fixture, path);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
check_level_length (fixture->filter, "2", LEVEL_LENGTH - 1);
+ signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "2:2");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
set_path_visibility (fixture, "2:2:2", TRUE);
check_filter_model_with_root (fixture, path);
@@ -786,10 +1331,17 @@ unfiltered_show_single (FilterTest *fixture,
gconstpointer user_data)
{
+ signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
set_path_visibility (fixture, "2", TRUE);
+ signal_monitor_assert_is_empty (fixture->monitor);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+ /* The view only shows the root level, so the filter model only has
+ * the first two levels cached.
+ */
+ filter_test_append_refilter_signals (fixture, 2);
filter_test_enable_filter (fixture);
check_filter_model (fixture);
@@ -801,11 +1353,18 @@ unfiltered_show_single_child (FilterTest *fixture,
gconstpointer user_data)
{
+ signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
set_path_visibility (fixture, "2:2", TRUE);
+ signal_monitor_assert_is_empty (fixture->monitor);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
check_level_length (fixture->filter, "2", LEVEL_LENGTH);
+ /* The view only shows the root level, so the filter model only has
+ * the first two levels cached.
+ */
+ filter_test_append_refilter_signals (fixture, 3);
filter_test_enable_filter (fixture);
check_filter_model (fixture);
@@ -814,7 +1373,10 @@ unfiltered_show_single_child (FilterTest *fixture,
/* From here we are filtered, "2" in the real model is "0" in the filter
* model.
*/
+ signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
set_path_visibility (fixture, "2", TRUE);
+ signal_monitor_assert_is_empty (fixture->monitor);
check_level_length (fixture->filter, NULL, 1);
check_level_length (fixture->filter, "0", 1);
}
@@ -824,13 +1386,24 @@ unfiltered_show_single_multi_level (FilterTest *fixture,
gconstpointer user_data)
{
+ /* The view is not showing this row (collapsed state), so it is not
+ * referenced. The signal should not go through.
+ */
set_path_visibility (fixture, "2:2:2", TRUE);
+
+ signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
set_path_visibility (fixture, "2:2", TRUE);
+ signal_monitor_assert_is_empty (fixture->monitor);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
check_level_length (fixture->filter, "2", LEVEL_LENGTH);
check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
+ /* The view only shows the root level, so the filter model only has
+ * the first two levels cached.
+ */
+ filter_test_append_refilter_signals (fixture, 3);
filter_test_enable_filter (fixture);
check_filter_model (fixture);
@@ -839,6 +1412,8 @@ unfiltered_show_single_multi_level (FilterTest *fixture,
/* From here we are filtered, "2" in the real model is "0" in the filter
* model.
*/
+ signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
set_path_visibility (fixture, "2", TRUE);
check_filter_model (fixture);
check_level_length (fixture->filter, NULL, 1);
@@ -854,10 +1429,17 @@ unfiltered_vroot_show_single (FilterTest *fixture,
{
GtkTreePath *path = (GtkTreePath *)user_data;
+ signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2");
set_path_visibility (fixture, "2:2", TRUE);
+ signal_monitor_assert_is_empty (fixture->monitor);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
+ /* The view only shows the root level, so the filter model only has
+ * the first two levels cached.
+ */
+ filter_test_append_refilter_signals_with_vroot (fixture, 3, path);
filter_test_enable_filter (fixture);
check_filter_model_with_root (fixture, path);
@@ -871,11 +1453,18 @@ unfiltered_vroot_show_single_child (FilterTest *fixture,
{
GtkTreePath *path = (GtkTreePath *)user_data;
+ signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
set_path_visibility (fixture, "2:2:2", TRUE);
+ signal_monitor_assert_is_empty (fixture->monitor);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
check_level_length (fixture->filter, "2", LEVEL_LENGTH);
+ /* The view only shows the root level, so the filter model only has
+ * the first two levels cached.
+ */
+ filter_test_append_refilter_signals_with_vroot (fixture, 2, path);
filter_test_enable_filter (fixture);
check_filter_model_with_root (fixture, path);
@@ -884,7 +1473,10 @@ unfiltered_vroot_show_single_child (FilterTest *fixture,
/* From here we are filtered, "2" in the real model is "0" in the filter
* model.
*/
+ signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
set_path_visibility (fixture, "2:2", TRUE);
+ signal_monitor_assert_is_empty (fixture->monitor);
check_level_length (fixture->filter, NULL, 1);
check_level_length (fixture->filter, "0", 1);
}
@@ -896,13 +1488,24 @@ unfiltered_vroot_show_single_multi_level (FilterTest *fixture,
{
GtkTreePath *path = (GtkTreePath *)user_data;
+ /* The view is not showing this row (collapsed state), so it is not
+ * referenced. The signal should not go through.
+ */
set_path_visibility (fixture, "2:2:2:2", TRUE);
+
+ signal_monitor_append_signal (fixture->monitor, ROW_CHANGED, "2:2");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "2:2");
set_path_visibility (fixture, "2:2:2", TRUE);
+ signal_monitor_assert_is_empty (fixture->monitor);
check_level_length (fixture->filter, NULL, LEVEL_LENGTH);
check_level_length (fixture->filter, "2", LEVEL_LENGTH);
check_level_length (fixture->filter, "2:2", LEVEL_LENGTH);
+ /* The view only shows the root level, so the filter model only has
+ * the first two levels cached.
+ */
+ filter_test_append_refilter_signals_with_vroot (fixture, 4, path);
filter_test_enable_filter (fixture);
check_filter_model_with_root (fixture, path);
@@ -911,6 +1514,8 @@ unfiltered_vroot_show_single_multi_level (FilterTest *fixture,
/* From here we are filtered, "2" in the real model is "0" in the filter
* model.
*/
+ signal_monitor_append_signal (fixture->monitor, ROW_INSERTED, "0");
+ signal_monitor_append_signal (fixture->monitor, ROW_HAS_CHILD_TOGGLED, "0");
set_path_visibility (fixture, "2:2", TRUE);
check_filter_model_with_root (fixture, path);
check_level_length (fixture->filter, NULL, 1);
@@ -1214,6 +1819,7 @@ specific_root_mixed_visibility (void)
filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
fixture.filter = GTK_TREE_MODEL_FILTER (filter);
+ fixture.monitor = NULL;
gtk_tree_model_filter_set_visible_column (fixture.filter, 1);
@@ -1248,6 +1854,7 @@ specific_has_child_filter (void)
fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
fixture.filter = GTK_TREE_MODEL_FILTER (filter);
+ fixture.monitor = NULL;
/* We will filter on parent state using a filter function. We will
* manually keep the boolean column in sync, so that we can use
@@ -1344,6 +1951,7 @@ specific_root_has_child_filter (void)
fixture.store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fixture.store), NULL);
fixture.filter = GTK_TREE_MODEL_FILTER (filter);
+ fixture.monitor = NULL;
/* We will filter on parent state using a filter function. We will
* manually keep the boolean column in sync, so that we can use
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]