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 | |
26 | GQuark changes_quark; |
27 | |
28 | static char * |
29 | model_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 | |
63 | static void |
64 | items_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 | |
93 | static void |
94 | free_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 | |
104 | static GSList *widgets = NULL; |
105 | |
106 | static GtkWidget * |
107 | create_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 | |
126 | static void |
127 | destroy_widgets (void) |
128 | { |
129 | g_slist_free_full (list: widgets, free_func: (GDestroyNotify) gtk_window_destroy); |
130 | widgets = NULL; |
131 | } |
132 | |
133 | static GtkPropertyLookupListModel * |
134 | new_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 | |
152 | static void |
153 | test_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 | |
164 | static void |
165 | test_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 | |
177 | static void |
178 | test_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 | |
201 | static void |
202 | test_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 | |
229 | int |
230 | main (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 | |