1/* GtkRBTree tests.
2 *
3 * Copyright (C) 2011, Red Hat, Inc.
4 * Authors: Benjamin Otte <otte@gnome.org>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <locale.h>
21
22#include <gtk/gtk.h>
23
24#include "gtk/gtkpropertylookuplistmodelprivate.h"
25
26GQuark changes_quark;
27
28static char *
29model_to_string (GListModel *model)
30{
31 GString *string = g_string_new (NULL);
32 gpointer item;
33 guint i;
34
35 for (i = 0; i < g_list_model_get_n_items (list: model); i++)
36 {
37 if (i > 0)
38 g_string_append (string, val: " ");
39 item = g_list_model_get_item (list: model, position: i);
40 g_string_append_printf (string, format: "%s", G_OBJECT_TYPE_NAME (item));
41 g_object_unref (object: item);
42 }
43
44 return g_string_free (string, FALSE);
45}
46
47#define assert_model(model, expected) G_STMT_START{ \
48 char *s = model_to_string (G_LIST_MODEL (model)); \
49 if (!g_str_equal (s, expected)) \
50 g_assertion_message_cmpstr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
51 #model " == " #expected, s, "==", expected); \
52 g_free (s); \
53}G_STMT_END
54
55#define assert_changes(model, expected) G_STMT_START{ \
56 GString *changes = g_object_get_qdata (G_OBJECT (model), changes_quark); \
57 if (!g_str_equal (changes->str, expected)) \
58 g_assertion_message_cmpstr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
59 #model " == " #expected, changes->str, "==", expected); \
60 g_string_set_size (changes, 0); \
61}G_STMT_END
62
63static void
64items_changed (GListModel *model,
65 guint position,
66 guint removed,
67 guint added,
68 GString *changes)
69{
70 g_assert_true (removed != 0 || added != 0);
71
72 if (changes->len)
73 g_string_append (string: changes, val: ", ");
74
75 if (removed == 1 && added == 0)
76 {
77 g_string_append_printf (string: changes, format: "-%u", position);
78 }
79 else if (removed == 0 && added == 1)
80 {
81 g_string_append_printf (string: changes, format: "+%u", position);
82 }
83 else
84 {
85 g_string_append_printf (string: changes, format: "%u", position);
86 if (removed > 0)
87 g_string_append_printf (string: changes, format: "-%u", removed);
88 if (added > 0)
89 g_string_append_printf (string: changes, format: "+%u", added);
90 }
91}
92
93static void
94free_changes (gpointer data)
95{
96 GString *changes = data;
97
98 /* all changes must have been checked via assert_changes() before */
99 g_assert_cmpstr (changes->str, ==, "");
100
101 g_string_free (string: changes, TRUE);
102}
103
104static GSList *widgets = NULL;
105
106static GtkWidget *
107create_widget_tree (void)
108{
109 GtkWidget *window, *box, *grid, *label;
110
111 window = gtk_window_new ();
112 widgets = g_slist_prepend (list: widgets, data: window);
113
114 box = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 0);
115 gtk_window_set_child (GTK_WINDOW (window), child: box);
116
117 grid = gtk_grid_new ();
118 gtk_box_append (GTK_BOX (box), child: grid);
119
120 label = gtk_label_new (str: "Hello World");
121 gtk_grid_attach (GTK_GRID (grid), child: label, column: 0, row: 0, width: 1, height: 1);
122
123 return label;
124}
125
126static void
127destroy_widgets (void)
128{
129 g_slist_free_full (list: widgets, free_func: (GDestroyNotify) gtk_window_destroy);
130 widgets = NULL;
131}
132
133static GtkPropertyLookupListModel *
134new_model (gboolean fill)
135{
136 GtkPropertyLookupListModel *result;
137 GString *changes;
138
139 result = gtk_property_lookup_list_model_new (GTK_TYPE_WIDGET, property_name: "parent");
140 if (fill)
141 {
142 GtkWidget *widget = create_widget_tree ();
143 gtk_property_lookup_list_model_set_object (self: result, object: widget);
144 }
145 changes = g_string_new (init: "");
146 g_object_set_qdata_full (G_OBJECT(result), quark: changes_quark, data: changes, destroy: free_changes);
147 g_signal_connect (result, "items-changed", G_CALLBACK (items_changed), changes);
148
149 return result;
150}
151
152static void
153test_create_empty (void)
154{
155 GtkPropertyLookupListModel *model;
156
157 model = new_model (FALSE);
158 assert_model (model, "");
159 assert_changes (model, "");
160
161 g_object_unref (object: model);
162}
163
164static void
165test_create (void)
166{
167 GtkPropertyLookupListModel *model;
168
169 model = new_model (TRUE);
170 assert_model (model, "GtkLabel GtkGrid GtkBox GtkWindow");
171 assert_changes (model, "");
172
173 g_object_unref (object: model);
174 destroy_widgets ();
175}
176
177static void
178test_set_object (void)
179{
180 GtkPropertyLookupListModel *model;
181 GtkWidget *widget;
182
183 widget = create_widget_tree ();
184
185 model = new_model (FALSE);
186 gtk_property_lookup_list_model_set_object (self: model, object: widget);
187 assert_model (model, "GtkLabel GtkGrid GtkBox GtkWindow");
188 assert_changes (model, "+0");
189 g_object_unref (object: model);
190
191 model = new_model (FALSE);
192 assert_model (model, "");
193 gtk_property_lookup_list_model_set_object (self: model, object: widget);
194 assert_model (model, "GtkLabel GtkGrid GtkBox GtkWindow");
195 assert_changes (model, "0+4");
196 g_object_unref (object: model);
197
198 destroy_widgets ();
199}
200
201static void
202test_change_property (void)
203{
204 GtkPropertyLookupListModel *model;
205 GtkWidget *widget, *parent, *grandparent;
206
207 widget = create_widget_tree ();
208 parent = gtk_widget_get_parent (widget);
209 grandparent = gtk_widget_get_parent (widget: parent);
210
211 model = new_model (FALSE);
212 assert_model (model, ""); /* make sure the model has a definite size */
213 gtk_property_lookup_list_model_set_object (self: model, object: widget);
214 assert_model (model, "GtkLabel GtkGrid GtkBox GtkWindow");
215 assert_changes (model, "0+4");
216
217 gtk_grid_remove (GTK_GRID (parent), child: widget);
218 assert_model (model, "GtkLabel");
219 assert_changes (model, "1-3");
220
221 gtk_box_append (GTK_BOX (grandparent), child: widget);
222 assert_model (model, "GtkLabel GtkBox GtkWindow");
223 assert_changes (model, "1+2");
224
225 g_object_unref (object: model);
226 destroy_widgets ();
227}
228
229int
230main (int argc, char *argv[])
231{
232 gtk_test_init (argcp: &argc, argvp: &argv);
233
234 changes_quark = g_quark_from_static_string (string: "What did I see? Can I believe what I saw?");
235
236 g_test_add_func (testpath: "/propertylookuplistmodel/create_empty", test_func: test_create_empty);
237 g_test_add_func (testpath: "/propertylookuplistmodel/create", test_func: test_create);
238 g_test_add_func (testpath: "/propertylookuplistmodel/set-object", test_func: test_set_object);
239 g_test_add_func (testpath: "/propertylookuplistmodel/change-property", test_func: test_change_property);
240
241 return g_test_run ();
242}
243

source code of gtk/testsuite/gtk/propertylookuplistmodel.c