1/* GtkStringList tests
2 *
3 * Copyright (C) 2020, Red Hat, Inc.
4 * Authors: Matthias Clasen
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 <gtk/gtk.h>
21
22static GQuark changes_quark;
23
24static char *
25model_to_string (GListModel *model)
26{
27 GtkStringList *self = GTK_STRING_LIST (ptr: model);
28 GString *string = g_string_new (NULL);
29 guint i;
30
31 for (i = 0; i < g_list_model_get_n_items (list: model); i++)
32 {
33 if (i > 0)
34 g_string_append (string, val: " ");
35 g_string_append_printf (string, format: "%s", gtk_string_list_get_string (self, position: i));
36 }
37
38 return g_string_free (string, FALSE);
39}
40
41#define assert_model(model, expected) G_STMT_START{ \
42 char *s = model_to_string (G_LIST_MODEL (model)); \
43 if (!g_str_equal (s, expected)) \
44 g_assertion_message_cmpstr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
45 #model " == " #expected, s, "==", expected); \
46 g_free (s); \
47}G_STMT_END
48
49#define assert_changes(model, expected) G_STMT_START{ \
50 GString *changes = g_object_get_qdata (G_OBJECT (model), changes_quark); \
51 if (!g_str_equal (changes->str, expected)) \
52 g_assertion_message_cmpstr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
53 #model " == " #expected, changes->str, "==", expected); \
54 g_string_set_size (changes, 0); \
55}G_STMT_END
56
57static void
58items_changed (GListModel *model,
59 guint position,
60 guint removed,
61 guint added,
62 GString *changes)
63{
64 g_assert_true (removed != 0 || added != 0);
65
66 if (changes->len)
67 g_string_append (string: changes, val: ", ");
68
69 if (removed == 1 && added == 0)
70 {
71 g_string_append_printf (string: changes, format: "-%u", position);
72 }
73 else if (removed == 0 && added == 1)
74 {
75 g_string_append_printf (string: changes, format: "+%u", position);
76 }
77 else
78 {
79 g_string_append_printf (string: changes, format: "%u", position);
80 if (removed > 0)
81 g_string_append_printf (string: changes, format: "-%u", removed);
82 if (added > 0)
83 g_string_append_printf (string: changes, format: "+%u", added);
84 }
85}
86
87static void
88free_changes (gpointer data)
89{
90 GString *changes = data;
91
92 /* all changes must have been checked via assert_changes() before */
93 g_assert_cmpstr (changes->str, ==, "");
94
95 g_string_free (string: changes, TRUE);
96}
97
98static GtkStringList *
99new_model (const char **strings)
100{
101 GtkStringList *result;
102 GString *changes;
103
104 result = gtk_string_list_new (strings);
105 changes = g_string_new (init: "");
106 g_object_set_qdata_full (G_OBJECT(result), quark: changes_quark, data: changes, destroy: free_changes);
107 g_signal_connect (result, "items-changed", G_CALLBACK (items_changed), changes);
108
109 return result;
110}
111
112static void
113test_string_object (void)
114{
115 GtkStringObject *so;
116
117 so = gtk_string_object_new (string: "Hello");
118 g_assert_cmpstr (gtk_string_object_get_string (so), ==, "Hello");
119 g_object_unref (object: so);
120}
121
122static void
123test_create_empty (void)
124{
125 GtkStringList *list;
126
127 list = new_model (strings: (const char *[]){ NULL });
128
129 g_assert_true (g_type_is_a (g_list_model_get_item_type (G_LIST_MODEL (list)), G_TYPE_OBJECT));
130
131 assert_model (list, "");
132 assert_changes (list, "");
133
134 g_object_unref (object: list);
135}
136
137static void
138test_create_strv (void)
139{
140 GtkStringList *list;
141
142 list = new_model (strings: (const char *[]){ "a", "b", "c", NULL });
143
144 assert_model (list, "a b c");
145 assert_changes (list, "");
146
147 g_object_unref (object: list);
148}
149
150static void
151test_create_builder (void)
152{
153 const char *ui =
154"<interface>"
155" <object class=\"GtkStringList\" id=\"list\">"
156" <items>"
157" <item translatable=\"yes\" context=\"ctx\" comments=\"none\">a</item>"
158" <item>b</item>"
159" <item>c</item>"
160" </items>"
161" </object>"
162"</interface>";
163 GtkBuilder *builder;
164 GtkStringList *list;
165
166 builder = gtk_builder_new_from_string (string: ui, length: -1);
167 list = GTK_STRING_LIST (ptr: gtk_builder_get_object (builder, name: "list"));
168 assert_model (list, "a b c");
169
170 g_object_unref (object: builder);
171}
172
173static void
174test_get_string (void)
175{
176 GtkStringList *list;
177
178 list = new_model (strings: (const char *[]){ "a", "b", "c", NULL });
179
180 assert_model (list, "a b c");
181
182 g_assert_cmpstr (gtk_string_list_get_string (list, 0), ==, "a");
183 g_assert_cmpstr (gtk_string_list_get_string (list, 1), ==, "b");
184 g_assert_cmpstr (gtk_string_list_get_string (list, 2), ==, "c");
185 g_assert_null (gtk_string_list_get_string (list, 3));
186
187 g_object_unref (object: list);
188}
189
190static void
191test_splice (void)
192{
193 GtkStringList *list;
194
195 list = new_model (strings: (const char *[]){ "a", "b", "c", "d", "e", NULL });
196
197 assert_model (list, "a b c d e");
198
199 gtk_string_list_splice (self: list, position: 2, n_removals: 2, additions: (const char *[]){ "x", "y", "z", NULL });
200
201 assert_model (list, "a b x y z e");
202 assert_changes (list, "2-2+3");
203
204 g_object_unref (object: list);
205}
206
207static void
208test_add_remove (void)
209{
210 GtkStringList *list;
211
212 list = new_model (strings: (const char *[]){ "a", "b", "c", "d", "e", NULL });
213
214 assert_model (list, "a b c d e");
215
216 gtk_string_list_remove (self: list, position: 2);
217
218 assert_model (list, "a b d e");
219 assert_changes (list, "-2");
220
221 gtk_string_list_append (self: list, string: "x");
222
223 assert_model (list, "a b d e x");
224 assert_changes (list, "+4");
225
226 g_object_unref (object: list);
227}
228
229static void
230test_take (void)
231{
232 GtkStringList *list;
233
234 list = new_model (strings: (const char *[]){ NULL });
235
236 assert_model (list, "");
237
238 gtk_string_list_take (self: list, string: g_strdup_printf (format: "%d dollars", (int)1e6));
239 assert_model (list, "1000000 dollars");
240 assert_changes (list, "+0");
241
242 g_object_unref (object: list);
243}
244
245int
246main (int argc, char *argv[])
247{
248 (g_test_init) (argc: &argc, argv: &argv, NULL);
249
250 changes_quark = g_quark_from_static_string (string: "What did I see? Can I believe what I saw?");
251
252 g_test_add_func (testpath: "/stringobject/basic", test_func: test_string_object);
253 g_test_add_func (testpath: "/stringlist/create/empty", test_func: test_create_empty);
254 g_test_add_func (testpath: "/stringlist/create/strv", test_func: test_create_strv);
255 g_test_add_func (testpath: "/stringlist/create/builder", test_func: test_create_builder);
256 g_test_add_func (testpath: "/stringlist/get_string", test_func: test_get_string);
257 g_test_add_func (testpath: "/stringlist/splice", test_func: test_splice);
258 g_test_add_func (testpath: "/stringlist/add_remove", test_func: test_add_remove);
259 g_test_add_func (testpath: "/stringlist/take", test_func: test_take);
260
261 return g_test_run ();
262}
263

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