1/* Extensive GtkListStore tests.
2 * Copyright (C) 2007 Imendio AB
3 * Authors: Kristian Rietveld <kris@imendio.com>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/* To do:
20 * - Test implementations of the interfaces: DnD, sortable, buildable
21 * and the tree model interface itself?
22 * - Need to check if the emitted signals are right.
23 * - Needs analysis with the code coverage tool once it is there.
24 */
25
26#include <gtk/gtk.h>
27
28#include "treemodel.h"
29
30static inline gboolean
31iters_equal (GtkTreeIter *a,
32 GtkTreeIter *b)
33{
34 if (a->stamp != b->stamp)
35 return FALSE;
36
37 if (a->user_data != b->user_data)
38 return FALSE;
39
40 /* user_data2 and user_data3 are not used in GtkListStore */
41
42 return TRUE;
43}
44
45static gboolean
46iter_position (GtkListStore *store,
47 GtkTreeIter *iter,
48 int n)
49{
50 gboolean ret = TRUE;
51 GtkTreePath *path;
52
53 path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter);
54 if (!path)
55 return FALSE;
56
57 if (gtk_tree_path_get_indices (path)[0] != n)
58 ret = FALSE;
59
60 gtk_tree_path_free (path);
61
62 return ret;
63}
64
65/*
66 * Fixture
67 */
68typedef struct
69{
70 GtkTreeIter iter[5];
71 GtkListStore *store;
72} ListStore;
73
74static void
75list_store_setup (ListStore *fixture,
76 gconstpointer test_data)
77{
78 int i;
79
80 fixture->store = gtk_list_store_new (n_columns: 1, G_TYPE_INT);
81
82 for (i = 0; i < 5; i++)
83 {
84 gtk_list_store_insert (list_store: fixture->store, iter: &fixture->iter[i], position: i);
85 gtk_list_store_set (list_store: fixture->store, iter: &fixture->iter[i], 0, i, -1);
86 }
87}
88
89static void
90list_store_teardown (ListStore *fixture,
91 gconstpointer test_data)
92{
93 g_object_unref (object: fixture->store);
94}
95
96/*
97 * The actual tests.
98 */
99
100static void
101check_model (ListStore *fixture,
102 int *new_order,
103 int skip)
104{
105 int i;
106 GtkTreePath *path;
107
108 path = gtk_tree_path_new ();
109 gtk_tree_path_down (path);
110
111 /* Check validity of the model and validity of the iters-persistent
112 * claim.
113 */
114 for (i = 0; i < 5; i++)
115 {
116 GtkTreeIter iter;
117
118 if (i == skip)
119 continue;
120
121 /* The saved iterator at new_order[i] should match the iterator
122 * at i.
123 */
124
125 gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
126 iter: &iter, path);
127
128 g_assert_true (gtk_list_store_iter_is_valid (fixture->store, &iter));
129 g_assert_true (iters_equal (&iter, &fixture->iter[new_order[i]]));
130
131 gtk_tree_path_next (path);
132 }
133
134 gtk_tree_path_free (path);
135}
136
137/* insertion */
138static void
139list_store_test_insert_high_values (void)
140{
141 GtkTreeIter iter, iter2;
142 GtkTreeIter iter_copy;
143 GtkListStore *store;
144
145 store = gtk_list_store_new (n_columns: 1, G_TYPE_INT);
146
147 gtk_list_store_insert (list_store: store, iter: &iter, position: 1234);
148 g_assert_true (gtk_list_store_iter_is_valid (store, &iter));
149 g_assert_cmpint (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL), ==, 1);
150 g_assert_true (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
151 g_assert_true (iters_equal (&iter, &iter_copy));
152 g_assert_true (iter_position (store, &iter, 0));
153
154 gtk_list_store_insert (list_store: store, iter: &iter2, position: 765);
155 g_assert_true (gtk_list_store_iter_is_valid (store, &iter2));
156 g_assert_cmpint (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL), ==, 2);
157
158 /* Walk over the model */
159 g_assert_true (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
160 g_assert_true (iters_equal (&iter, &iter_copy));
161 g_assert_true (iter_position (store, &iter, 0));
162
163 g_assert_true (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
164 g_assert_true (iters_equal (&iter2, &iter_copy));
165 g_assert_true (iter_position (store, &iter2, 1));
166
167 g_assert_false (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
168
169 g_assert_true (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
170 g_assert_true (iters_equal (&iter2, &iter_copy));
171 g_assert_true (iter_position (store, &iter2, 1));
172
173 g_assert_true (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
174 g_assert_true (iters_equal (&iter, &iter_copy));
175 g_assert_true (iter_position (store, &iter, 0));
176
177 g_assert_false (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
178
179 g_object_unref (object: store);
180}
181
182static void
183list_store_test_append (void)
184{
185 GtkTreeIter iter, iter2;
186 GtkTreeIter iter_copy;
187 GtkListStore *store;
188
189 store = gtk_list_store_new (n_columns: 1, G_TYPE_INT);
190
191 gtk_list_store_append (list_store: store, iter: &iter);
192 g_assert_true (gtk_list_store_iter_is_valid (store, &iter));
193 g_assert_cmpint (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL), ==, 1);
194 g_assert_true (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
195 g_assert_true (iters_equal (&iter, &iter_copy));
196 g_assert_true (iter_position (store, &iter, 0));
197
198 gtk_list_store_append (list_store: store, iter: &iter2);
199 g_assert_true (gtk_list_store_iter_is_valid (store, &iter2));
200 g_assert_cmpint (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL), ==, 2);
201
202 /* Walk over the model */
203 g_assert_true (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
204 g_assert_true (iters_equal (&iter, &iter_copy));
205 g_assert_true (iter_position (store, &iter, 0));
206
207 g_assert_true (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
208 g_assert_true (iters_equal (&iter2, &iter_copy));
209 g_assert_true (iter_position (store, &iter2, 1));
210
211 g_assert_false (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
212
213 g_assert_true (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
214 g_assert_true (iters_equal (&iter2, &iter_copy));
215 g_assert_true (iter_position (store, &iter2, 1));
216
217 g_assert_true (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
218 g_assert_true (iters_equal (&iter, &iter_copy));
219 g_assert_true (iter_position (store, &iter, 0));
220
221 g_assert_false (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
222
223 g_object_unref (object: store);
224}
225
226static void
227list_store_test_prepend (void)
228{
229 GtkTreeIter iter, iter2;
230 GtkTreeIter iter_copy;
231 GtkListStore *store;
232
233 store = gtk_list_store_new (n_columns: 1, G_TYPE_INT);
234
235 gtk_list_store_prepend (list_store: store, iter: &iter);
236 g_assert_true (gtk_list_store_iter_is_valid (store, &iter));
237 g_assert_cmpint (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL), ==, 1);
238 g_assert_true (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
239 g_assert_true (iters_equal (&iter, &iter_copy));
240 g_assert_true (iter_position (store, &iter, 0));
241
242 gtk_list_store_prepend (list_store: store, iter: &iter2);
243 g_assert_true (gtk_list_store_iter_is_valid (store, &iter2));
244 g_assert_cmpint (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL), ==, 2);
245
246 /* Walk over the model */
247 g_assert_true (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
248 g_assert_true (iters_equal (&iter2, &iter_copy));
249 g_assert_true (iter_position (store, &iter2, 0));
250
251 g_assert_true (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
252 g_assert_true (iters_equal (&iter, &iter_copy));
253 g_assert_true (iter_position (store, &iter, 1));
254
255 g_assert_false (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
256
257 g_assert_true (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
258 g_assert_true (iters_equal (&iter, &iter_copy));
259 g_assert_true (iter_position (store, &iter, 1));
260
261 g_assert_true (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
262 g_assert_true (iters_equal (&iter2, &iter_copy));
263 g_assert_true (iter_position (store, &iter2, 0));
264
265 g_assert_false (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
266
267 g_object_unref (object: store);
268}
269
270static void
271list_store_test_insert_after (void)
272{
273 GtkTreeIter iter, iter2, iter3;
274 GtkTreeIter iter_copy;
275 GtkListStore *store;
276
277 store = gtk_list_store_new (n_columns: 1, G_TYPE_INT);
278
279 gtk_list_store_append (list_store: store, iter: &iter);
280 gtk_list_store_append (list_store: store, iter: &iter2);
281
282 gtk_list_store_insert_after (list_store: store, iter: &iter3, sibling: &iter);
283 g_assert_true (gtk_list_store_iter_is_valid (store, &iter3));
284 g_assert_cmpint (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL), ==, 3);
285 g_assert_true (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
286 g_assert_true (iters_equal (&iter3, &iter_copy));
287 g_assert_true (iter_position (store, &iter3, 1));
288
289 /* Walk over the model */
290 g_assert_true (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
291 g_assert_true (iters_equal (&iter, &iter_copy));
292 g_assert_true (iter_position (store, &iter_copy, 0));
293
294 g_assert_true (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
295 g_assert_true (iters_equal (&iter3, &iter_copy));
296 g_assert_true (iter_position (store, &iter_copy, 1));
297
298 g_assert_true (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
299 g_assert_true (iters_equal (&iter2, &iter_copy));
300 g_assert_true (iter_position (store, &iter_copy, 2));
301
302 g_assert_false (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
303
304 g_assert_true (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 2));
305 g_assert_true (iters_equal (&iter2, &iter_copy));
306 g_assert_true (iter_position (store, &iter2, 2));
307
308 g_assert_true (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
309 g_assert_true (iters_equal (&iter3, &iter_copy));
310 g_assert_true (iter_position (store, &iter3, 1));
311
312 g_assert_true (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
313 g_assert_true (iters_equal (&iter, &iter_copy));
314 g_assert_true (iter_position (store, &iter, 0));
315
316 g_assert_false (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
317
318 g_object_unref (object: store);
319}
320
321static void
322list_store_test_insert_after_NULL (void)
323{
324 GtkTreeIter iter, iter2;
325 GtkTreeIter iter_copy;
326 GtkListStore *store;
327
328 store = gtk_list_store_new (n_columns: 1, G_TYPE_INT);
329
330 gtk_list_store_append (list_store: store, iter: &iter);
331
332 /* move_after NULL is basically a prepend */
333 gtk_list_store_insert_after (list_store: store, iter: &iter2, NULL);
334 g_assert_true (gtk_list_store_iter_is_valid (store, &iter2));
335 g_assert_cmpint (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL), ==, 2);
336
337 /* Walk over the model */
338 g_assert_true (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
339 g_assert_true (iters_equal (&iter2, &iter_copy));
340 g_assert_true (iter_position (store, &iter2, 0));
341
342 g_assert_true (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
343 g_assert_true (iters_equal (&iter, &iter_copy));
344 g_assert_true (iter_position (store, &iter, 1));
345
346 g_assert_false (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
347
348 g_assert_true (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 0));
349 g_assert_true (iters_equal (&iter2, &iter_copy));
350
351 g_assert_true (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
352 g_assert_true (iters_equal (&iter, &iter_copy));
353 g_assert_true (iter_position (store, &iter, 1));
354
355 g_assert_true (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
356 g_assert_true (iters_equal (&iter2, &iter_copy));
357 g_assert_true (iter_position (store, &iter2, 0));
358
359 g_assert_false (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
360
361 g_object_unref (object: store);
362}
363
364static void
365list_store_test_insert_before (void)
366{
367 GtkTreeIter iter, iter2, iter3;
368 GtkTreeIter iter_copy;
369 GtkListStore *store;
370
371 store = gtk_list_store_new (n_columns: 1, G_TYPE_INT);
372
373 gtk_list_store_append (list_store: store, iter: &iter);
374 gtk_list_store_append (list_store: store, iter: &iter2);
375
376 gtk_list_store_insert_before (list_store: store, iter: &iter3, sibling: &iter2);
377 g_assert_true (gtk_list_store_iter_is_valid (store, &iter3));
378 g_assert_cmpint (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL), ==, 3);
379 g_assert_true (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
380 g_assert_true (iters_equal (&iter3, &iter_copy));
381 g_assert_true (iter_position (store, &iter3, 1));
382
383 /* Walk over the model */
384 g_assert_true (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
385 g_assert_true (iters_equal (&iter, &iter_copy));
386 g_assert_true (iter_position (store, &iter_copy, 0));
387
388 g_assert_true (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
389 g_assert_true (iters_equal (&iter3, &iter_copy));
390 g_assert_true (iter_position (store, &iter_copy, 1));
391
392 g_assert_true (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
393 g_assert_true (iters_equal (&iter2, &iter_copy));
394 g_assert_true (iter_position (store, &iter_copy, 2));
395
396 g_assert_false (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
397
398 g_assert_true (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
399 g_assert_true (iters_equal (&iter3, &iter_copy));
400
401 g_assert_true (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 2));
402 g_assert_true (iters_equal (&iter2, &iter_copy));
403 g_assert_true (iter_position (store, &iter2, 2));
404
405 g_assert_true (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
406 g_assert_true (iters_equal (&iter3, &iter_copy));
407 g_assert_true (iter_position (store, &iter3, 1));
408
409 g_assert_true (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
410 g_assert_true (iters_equal (&iter, &iter_copy));
411 g_assert_true (iter_position (store, &iter, 0));
412
413 g_assert_false (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
414
415 g_object_unref (object: store);
416}
417
418static void
419list_store_test_insert_before_NULL (void)
420{
421 GtkTreeIter iter, iter2;
422 GtkTreeIter iter_copy;
423 GtkListStore *store;
424
425 store = gtk_list_store_new (n_columns: 1, G_TYPE_INT);
426
427 gtk_list_store_append (list_store: store, iter: &iter);
428
429 /* move_before NULL is basically an append */
430 gtk_list_store_insert_before (list_store: store, iter: &iter2, NULL);
431 g_assert_true (gtk_list_store_iter_is_valid (store, &iter2));
432 g_assert_cmpint (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL), ==, 2);
433
434 /* Walk over the model */
435 g_assert_true (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
436 g_assert_true (iters_equal (&iter, &iter_copy));
437 g_assert_true (iter_position (store, &iter, 0));
438
439 g_assert_true (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
440 g_assert_true (iters_equal (&iter2, &iter_copy));
441 g_assert_true (iter_position (store, &iter2, 1));
442
443 g_assert_false (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
444
445 g_assert_true (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
446 g_assert_true (iters_equal (&iter2, &iter_copy));
447 g_assert_true (iter_position (store, &iter2, 1));
448
449 g_assert_true (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
450 g_assert_true (iters_equal (&iter, &iter_copy));
451 g_assert_true (iter_position (store, &iter, 0));
452
453 g_assert_false (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
454
455 g_object_unref (object: store);
456}
457
458/* setting values */
459static void
460list_store_set_gvalue_to_transform (void)
461{
462 GtkListStore *store;
463 GtkTreeIter iter;
464 GValue value = G_VALUE_INIT;
465
466 /* https://bugzilla.gnome.org/show_bug.cgi?id=677649 */
467 store = gtk_list_store_new (n_columns: 1, G_TYPE_LONG);
468 gtk_list_store_append (list_store: store, iter: &iter);
469
470 g_value_init (value: &value, G_TYPE_INT);
471 g_value_set_int (value: &value, v_int: 42);
472 gtk_list_store_set_value (list_store: store, iter: &iter, column: 0, value: &value);
473}
474
475/* removal */
476static void
477list_store_test_remove_begin (ListStore *fixture,
478 gconstpointer user_data)
479{
480 int new_order[5] = { -1, 1, 2, 3, 4 };
481 GtkTreePath *path;
482 GtkTreeIter iter;
483
484 /* Remove node at 0 */
485 path = gtk_tree_path_new_from_indices (first_index: 0, -1);
486 gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), iter: &iter, path);
487 gtk_tree_path_free (path);
488
489 g_assert_true (gtk_list_store_remove (fixture->store, &iter));
490 g_assert_false (gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[0]));
491 g_assert_true (iters_equal (&iter, &fixture->iter[1]));
492
493 check_model (fixture, new_order, skip: 0);
494}
495
496static void
497list_store_test_remove_middle (ListStore *fixture,
498 gconstpointer user_data)
499{
500 int new_order[5] = { 0, 1, -1, 3, 4 };
501 GtkTreePath *path;
502 GtkTreeIter iter;
503
504 /* Remove node at 2 */
505 path = gtk_tree_path_new_from_indices (first_index: 2, -1);
506 gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), iter: &iter, path);
507 gtk_tree_path_free (path);
508
509 g_assert_true (gtk_list_store_remove (fixture->store, &iter));
510 g_assert_false (gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[2]));
511 g_assert_true (iters_equal (&iter, &fixture->iter[3]));
512
513 check_model (fixture, new_order, skip: 2);
514}
515
516static void
517list_store_test_remove_end (ListStore *fixture,
518 gconstpointer user_data)
519{
520 int new_order[5] = { 0, 1, 2, 3, -1 };
521 GtkTreePath *path;
522 GtkTreeIter iter;
523
524 /* Remove node at 4 */
525 path = gtk_tree_path_new_from_indices (first_index: 4, -1);
526 gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), iter: &iter, path);
527 gtk_tree_path_free (path);
528
529 g_assert_false (gtk_list_store_remove (fixture->store, &iter));
530 g_assert_false (gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[4]));
531
532 check_model (fixture, new_order, skip: 4);
533}
534
535static void
536list_store_test_clear (ListStore *fixture,
537 gconstpointer user_data)
538{
539 int i;
540
541 gtk_list_store_clear (list_store: fixture->store);
542
543 g_assert_cmpint (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (fixture->store), NULL), ==, 0);
544
545 for (i = 0; i < 5; i++)
546 g_assert_true (!gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[i]));
547}
548
549/* reorder */
550
551static void
552list_store_test_reorder (ListStore *fixture,
553 gconstpointer user_data)
554{
555 int new_order[5] = { 4, 1, 0, 2, 3 };
556
557 gtk_list_store_reorder (store: fixture->store, new_order);
558 check_model (fixture, new_order, skip: -1);
559}
560
561/* swapping */
562
563static void
564list_store_test_swap_begin (ListStore *fixture,
565 gconstpointer user_data)
566{
567 /* We swap nodes 0 and 1 at the beginning */
568 int new_order[5] = { 1, 0, 2, 3, 4 };
569
570 GtkTreeIter iter_a;
571 GtkTreeIter iter_b;
572
573 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "0"));
574 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "1"));
575
576 gtk_list_store_swap (store: fixture->store, a: &iter_a, b: &iter_b);
577 check_model (fixture, new_order, skip: -1);
578}
579
580static void
581list_store_test_swap_middle_next (ListStore *fixture,
582 gconstpointer user_data)
583{
584 /* We swap nodes 2 and 3 in the middle that are next to each other */
585 int new_order[5] = { 0, 1, 3, 2, 4 };
586
587 GtkTreeIter iter_a;
588 GtkTreeIter iter_b;
589
590 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "2"));
591 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "3"));
592
593 gtk_list_store_swap (store: fixture->store, a: &iter_a, b: &iter_b);
594 check_model (fixture, new_order, skip: -1);
595}
596
597static void
598list_store_test_swap_middle_apart (ListStore *fixture,
599 gconstpointer user_data)
600{
601 /* We swap nodes 1 and 3 in the middle that are apart from each other */
602 int new_order[5] = { 0, 3, 2, 1, 4 };
603
604 GtkTreeIter iter_a;
605 GtkTreeIter iter_b;
606
607 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "1"));
608 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "3"));
609
610 gtk_list_store_swap (store: fixture->store, a: &iter_a, b: &iter_b);
611 check_model (fixture, new_order, skip: -1);
612}
613
614static void
615list_store_test_swap_end (ListStore *fixture,
616 gconstpointer user_data)
617{
618 /* We swap nodes 3 and 4 at the end */
619 int new_order[5] = { 0, 1, 2, 4, 3 };
620
621 GtkTreeIter iter_a;
622 GtkTreeIter iter_b;
623
624 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "3"));
625 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "4"));
626
627 gtk_list_store_swap (store: fixture->store, a: &iter_a, b: &iter_b);
628 check_model (fixture, new_order, skip: -1);
629}
630
631static void
632list_store_test_swap_single (void)
633{
634 GtkTreeIter iter;
635 GtkTreeIter iter_copy;
636 GtkListStore *store;
637
638 store = gtk_list_store_new (n_columns: 1, G_TYPE_INT);
639
640 /* Check if swap on a store with a single node does not corrupt
641 * the store.
642 */
643
644 gtk_list_store_append (list_store: store, iter: &iter);
645 iter_copy = iter;
646
647 gtk_list_store_swap (store, a: &iter, b: &iter);
648 g_assert_true (iters_equal (&iter, &iter_copy));
649 g_assert_true (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
650 g_assert_true (iters_equal (&iter, &iter_copy));
651
652 g_object_unref (object: store);
653}
654
655/* move after */
656
657static void
658list_store_test_move_after_from_start (ListStore *fixture,
659 gconstpointer user_data)
660{
661 /* We move node 0 after 2 */
662 int new_order[5] = { 1, 2, 0, 3, 4 };
663
664 GtkTreeIter iter;
665 GtkTreeIter position;
666
667 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "0"));
668 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "2"));
669
670 gtk_list_store_move_after (store: fixture->store, iter: &iter, position: &position);
671 check_model (fixture, new_order, skip: -1);
672}
673
674static void
675list_store_test_move_after_next (ListStore *fixture,
676 gconstpointer user_data)
677{
678 /* We move node 2 after 3 */
679 int new_order[5] = { 0, 1, 3, 2, 4 };
680
681 GtkTreeIter iter;
682 GtkTreeIter position;
683
684 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
685 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "3"));
686
687 gtk_list_store_move_after (store: fixture->store, iter: &iter, position: &position);
688 check_model (fixture, new_order, skip: -1);
689}
690
691static void
692list_store_test_move_after_apart (ListStore *fixture,
693 gconstpointer user_data)
694{
695 /* We move node 1 after 3 */
696 int new_order[5] = { 0, 2, 3, 1, 4 };
697
698 GtkTreeIter iter;
699 GtkTreeIter position;
700
701 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "1"));
702 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "3"));
703
704 gtk_list_store_move_after (store: fixture->store, iter: &iter, position: &position);
705 check_model (fixture, new_order, skip: -1);
706}
707
708static void
709list_store_test_move_after_end (ListStore *fixture,
710 gconstpointer user_data)
711{
712 /* We move node 2 after 4 */
713 int new_order[5] = { 0, 1, 3, 4, 2 };
714
715 GtkTreeIter iter;
716 GtkTreeIter position;
717
718 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
719 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "4"));
720
721 gtk_list_store_move_after (store: fixture->store, iter: &iter, position: &position);
722 check_model (fixture, new_order, skip: -1);
723}
724
725static void
726list_store_test_move_after_from_end (ListStore *fixture,
727 gconstpointer user_data)
728{
729 /* We move node 4 after 1 */
730 int new_order[5] = { 0, 1, 4, 2, 3 };
731
732 GtkTreeIter iter;
733 GtkTreeIter position;
734
735 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "4"));
736 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "1"));
737
738 gtk_list_store_move_after (store: fixture->store, iter: &iter, position: &position);
739 check_model (fixture, new_order, skip: -1);
740}
741
742static void
743list_store_test_move_after_change_ends (ListStore *fixture,
744 gconstpointer user_data)
745{
746 /* We move 0 after 4, this will cause both the head and tail ends to
747 * change.
748 */
749 int new_order[5] = { 1, 2, 3, 4, 0 };
750
751 GtkTreeIter iter;
752 GtkTreeIter position;
753
754 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "0"));
755 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "4"));
756
757 gtk_list_store_move_after (store: fixture->store, iter: &iter, position: &position);
758 check_model (fixture, new_order, skip: -1);
759}
760
761static void
762list_store_test_move_after_NULL (ListStore *fixture,
763 gconstpointer user_data)
764{
765 /* We move node 2, NULL should prepend */
766 int new_order[5] = { 2, 0, 1, 3, 4 };
767
768 GtkTreeIter iter;
769
770 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
771
772 gtk_list_store_move_after (store: fixture->store, iter: &iter, NULL);
773 check_model (fixture, new_order, skip: -1);
774}
775
776static void
777list_store_test_move_after_single (void)
778{
779 GtkTreeIter iter;
780 GtkTreeIter iter_copy;
781 GtkListStore *store;
782
783 store = gtk_list_store_new (n_columns: 1, G_TYPE_INT);
784
785 /* Check if move-after on a store with a single node does not corrupt
786 * the store.
787 */
788
789 gtk_list_store_append (list_store: store, iter: &iter);
790 iter_copy = iter;
791
792 gtk_list_store_move_after (store, iter: &iter, NULL);
793 g_assert_true (iters_equal (&iter, &iter_copy));
794 g_assert_true (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
795 g_assert_true (iters_equal (&iter, &iter_copy));
796
797 gtk_list_store_move_after (store, iter: &iter, position: &iter);
798 g_assert_true (iters_equal (&iter, &iter_copy));
799 g_assert_true (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
800 g_assert_true (iters_equal (&iter, &iter_copy));
801
802 g_object_unref (object: store);
803}
804
805/* move before */
806
807static void
808list_store_test_move_before_next (ListStore *fixture,
809 gconstpointer user_data)
810{
811 /* We move node 3 before 2 */
812 int new_order[5] = { 0, 1, 3, 2, 4 };
813
814 GtkTreeIter iter;
815 GtkTreeIter position;
816
817 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "3"));
818 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "2"));
819
820 gtk_list_store_move_before (store: fixture->store, iter: &iter, position: &position);
821 check_model (fixture, new_order, skip: -1);
822}
823
824static void
825list_store_test_move_before_apart (ListStore *fixture,
826 gconstpointer user_data)
827{
828 /* We move node 1 before 3 */
829 int new_order[5] = { 0, 2, 1, 3, 4 };
830
831 GtkTreeIter iter;
832 GtkTreeIter position;
833
834 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "1"));
835 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "3"));
836
837 gtk_list_store_move_before (store: fixture->store, iter: &iter, position: &position);
838 check_model (fixture, new_order, skip: -1);
839}
840
841static void
842list_store_test_move_before_to_start (ListStore *fixture,
843 gconstpointer user_data)
844{
845 /* We move node 2 before 0 */
846 int new_order[5] = { 2, 0, 1, 3, 4 };
847
848 GtkTreeIter iter;
849 GtkTreeIter position;
850
851 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
852 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "0"));
853
854 gtk_list_store_move_before (store: fixture->store, iter: &iter, position: &position);
855 check_model (fixture, new_order, skip: -1);
856}
857
858static void
859list_store_test_move_before_from_end (ListStore *fixture,
860 gconstpointer user_data)
861{
862 /* We move node 4 before 2 (replace end) */
863 int new_order[5] = { 0, 1, 4, 2, 3 };
864
865 GtkTreeIter iter;
866 GtkTreeIter position;
867
868 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "4"));
869 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "2"));
870
871 gtk_list_store_move_before (store: fixture->store, iter: &iter, position: &position);
872 check_model (fixture, new_order, skip: -1);
873}
874
875static void
876list_store_test_move_before_change_ends (ListStore *fixture,
877 gconstpointer user_data)
878{
879 /* We move node 4 before 0 */
880 int new_order[5] = { 4, 0, 1, 2, 3 };
881
882 GtkTreeIter iter;
883 GtkTreeIter position;
884
885 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "4"));
886 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "0"));
887
888 gtk_list_store_move_before (store: fixture->store, iter: &iter, position: &position);
889 check_model (fixture, new_order, skip: -1);
890}
891
892static void
893list_store_test_move_before_NULL (ListStore *fixture,
894 gconstpointer user_data)
895{
896 /* We move node 2, NULL should append */
897 int new_order[5] = { 0, 1, 3, 4, 2 };
898
899 GtkTreeIter iter;
900
901 g_assert_true (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
902
903 gtk_list_store_move_before (store: fixture->store, iter: &iter, NULL);
904 check_model (fixture, new_order, skip: -1);
905}
906
907static void
908list_store_test_move_before_single (void)
909{
910 GtkTreeIter iter;
911 GtkTreeIter iter_copy;
912 GtkListStore *store;
913
914 store = gtk_list_store_new (n_columns: 1, G_TYPE_INT);
915
916 /* Check if move-before on a store with a single node does not corrupt
917 * the store.
918 */
919
920 gtk_list_store_append (list_store: store, iter: &iter);
921 iter_copy = iter;
922
923 gtk_list_store_move_before (store, iter: &iter, NULL);
924 g_assert_true (iters_equal (&iter, &iter_copy));
925 g_assert_true (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
926 g_assert_true (iters_equal (&iter, &iter_copy));
927
928 gtk_list_store_move_before (store, iter: &iter, position: &iter);
929 g_assert_true (iters_equal (&iter, &iter_copy));
930 g_assert_true (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
931 g_assert_true (iters_equal (&iter, &iter_copy));
932
933 g_object_unref (object: store);
934}
935
936
937/* iter invalidation */
938
939static void
940list_store_test_iter_previous_invalid (ListStore *fixture,
941 gconstpointer user_data)
942{
943 GtkTreeIter iter;
944
945 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), iter: &iter);
946
947 g_assert_false (gtk_tree_model_iter_previous (GTK_TREE_MODEL (fixture->store),
948 &iter));
949 g_assert_false (gtk_list_store_iter_is_valid (fixture->store, &iter));
950 g_assert_true (iter.stamp == 0);
951}
952
953static void
954list_store_test_iter_next_invalid (ListStore *fixture,
955 gconstpointer user_data)
956{
957 GtkTreePath *path;
958 GtkTreeIter iter;
959
960 path = gtk_tree_path_new_from_indices (first_index: 4, -1);
961 gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), iter: &iter, path);
962 gtk_tree_path_free (path);
963
964 g_assert_false (gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store),
965 &iter));
966 g_assert_false (gtk_list_store_iter_is_valid (fixture->store, &iter));
967 g_assert_true (iter.stamp == 0);
968}
969
970static void
971list_store_test_iter_children_invalid (ListStore *fixture,
972 gconstpointer user_data)
973{
974 GtkTreeIter iter, child;
975
976 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), iter: &iter);
977 g_assert_true (gtk_list_store_iter_is_valid (fixture->store, &iter));
978
979 g_assert_false (gtk_tree_model_iter_children (GTK_TREE_MODEL (fixture->store),
980 &child, &iter));
981 g_assert_false (gtk_list_store_iter_is_valid (fixture->store, &child));
982 g_assert_true (child.stamp == 0);
983}
984
985static void
986list_store_test_iter_nth_child_invalid (ListStore *fixture,
987 gconstpointer user_data)
988{
989 GtkTreeIter iter, child;
990
991 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), iter: &iter);
992 g_assert_true (gtk_list_store_iter_is_valid (fixture->store, &iter));
993
994 g_assert_false (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (fixture->store),
995 &child, &iter, 0));
996 g_assert_false (gtk_list_store_iter_is_valid (fixture->store, &child));
997 g_assert_true (child.stamp == 0);
998}
999
1000static void
1001list_store_test_iter_parent_invalid (ListStore *fixture,
1002 gconstpointer user_data)
1003{
1004 GtkTreeIter iter, child;
1005
1006 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), iter: &child);
1007 g_assert_true (gtk_list_store_iter_is_valid (fixture->store, &child));
1008
1009 g_assert_false (gtk_tree_model_iter_parent (GTK_TREE_MODEL (fixture->store),
1010 &iter, &child));
1011 g_assert_false (gtk_list_store_iter_is_valid (fixture->store, &iter));
1012 g_assert_true (iter.stamp == 0);
1013}
1014
1015
1016/* main */
1017
1018void
1019register_list_store_tests (void)
1020{
1021 /* insertion */
1022 g_test_add_func (testpath: "/ListStore/insert-high-values",
1023 test_func: list_store_test_insert_high_values);
1024 g_test_add_func (testpath: "/ListStore/append",
1025 test_func: list_store_test_append);
1026 g_test_add_func (testpath: "/ListStore/prepend",
1027 test_func: list_store_test_prepend);
1028 g_test_add_func (testpath: "/ListStore/insert-after",
1029 test_func: list_store_test_insert_after);
1030 g_test_add_func (testpath: "/ListStore/insert-after-NULL",
1031 test_func: list_store_test_insert_after_NULL);
1032 g_test_add_func (testpath: "/ListStore/insert-before",
1033 test_func: list_store_test_insert_before);
1034 g_test_add_func (testpath: "/ListStore/insert-before-NULL",
1035 test_func: list_store_test_insert_before_NULL);
1036
1037 /* setting values (FIXME) */
1038 g_test_add_func (testpath: "/ListStore/set-gvalue-to-transform",
1039 test_func: list_store_set_gvalue_to_transform);
1040
1041 /* removal */
1042 g_test_add ("/ListStore/remove-begin", ListStore, NULL,
1043 list_store_setup, list_store_test_remove_begin,
1044 list_store_teardown);
1045 g_test_add ("/ListStore/remove-middle", ListStore, NULL,
1046 list_store_setup, list_store_test_remove_middle,
1047 list_store_teardown);
1048 g_test_add ("/ListStore/remove-end", ListStore, NULL,
1049 list_store_setup, list_store_test_remove_end,
1050 list_store_teardown);
1051
1052 g_test_add ("/ListStore/clear", ListStore, NULL,
1053 list_store_setup, list_store_test_clear,
1054 list_store_teardown);
1055
1056 /* reordering */
1057 g_test_add ("/ListStore/reorder", ListStore, NULL,
1058 list_store_setup, list_store_test_reorder,
1059 list_store_teardown);
1060
1061 /* swapping */
1062 g_test_add ("/ListStore/swap-begin", ListStore, NULL,
1063 list_store_setup, list_store_test_swap_begin,
1064 list_store_teardown);
1065 g_test_add ("/ListStore/swap-middle-next", ListStore, NULL,
1066 list_store_setup, list_store_test_swap_middle_next,
1067 list_store_teardown);
1068 g_test_add ("/ListStore/swap-middle-apart", ListStore, NULL,
1069 list_store_setup, list_store_test_swap_middle_apart,
1070 list_store_teardown);
1071 g_test_add ("/ListStore/swap-end", ListStore, NULL,
1072 list_store_setup, list_store_test_swap_end,
1073 list_store_teardown);
1074 g_test_add_func (testpath: "/ListStore/swap-single",
1075 test_func: list_store_test_swap_single);
1076
1077 /* moving */
1078 g_test_add ("/ListStore/move-after-from-start", ListStore, NULL,
1079 list_store_setup, list_store_test_move_after_from_start,
1080 list_store_teardown);
1081 g_test_add ("/ListStore/move-after-next", ListStore, NULL,
1082 list_store_setup, list_store_test_move_after_next,
1083 list_store_teardown);
1084 g_test_add ("/ListStore/move-after-apart", ListStore, NULL,
1085 list_store_setup, list_store_test_move_after_apart,
1086 list_store_teardown);
1087 g_test_add ("/ListStore/move-after-end", ListStore, NULL,
1088 list_store_setup, list_store_test_move_after_end,
1089 list_store_teardown);
1090 g_test_add ("/ListStore/move-after-from-end", ListStore, NULL,
1091 list_store_setup, list_store_test_move_after_from_end,
1092 list_store_teardown);
1093 g_test_add ("/ListStore/move-after-change-ends", ListStore, NULL,
1094 list_store_setup, list_store_test_move_after_change_ends,
1095 list_store_teardown);
1096 g_test_add ("/ListStore/move-after-NULL", ListStore, NULL,
1097 list_store_setup, list_store_test_move_after_NULL,
1098 list_store_teardown);
1099 g_test_add_func (testpath: "/ListStore/move-after-single",
1100 test_func: list_store_test_move_after_single);
1101
1102 g_test_add ("/ListStore/move-before-next", ListStore, NULL,
1103 list_store_setup, list_store_test_move_before_next,
1104 list_store_teardown);
1105 g_test_add ("/ListStore/move-before-apart", ListStore, NULL,
1106 list_store_setup, list_store_test_move_before_apart,
1107 list_store_teardown);
1108 g_test_add ("/ListStore/move-before-to-start", ListStore, NULL,
1109 list_store_setup, list_store_test_move_before_to_start,
1110 list_store_teardown);
1111 g_test_add ("/ListStore/move-before-from-end", ListStore, NULL,
1112 list_store_setup, list_store_test_move_before_from_end,
1113 list_store_teardown);
1114 g_test_add ("/ListStore/move-before-change-ends", ListStore, NULL,
1115 list_store_setup, list_store_test_move_before_change_ends,
1116 list_store_teardown);
1117 g_test_add ("/ListStore/move-before-NULL", ListStore, NULL,
1118 list_store_setup, list_store_test_move_before_NULL,
1119 list_store_teardown);
1120 g_test_add_func (testpath: "/ListStore/move-before-single",
1121 test_func: list_store_test_move_before_single);
1122
1123 /* iter invalidation */
1124 g_test_add ("/ListStore/iter-prev-invalid", ListStore, NULL,
1125 list_store_setup, list_store_test_iter_previous_invalid,
1126 list_store_teardown);
1127 g_test_add ("/ListStore/iter-next-invalid", ListStore, NULL,
1128 list_store_setup, list_store_test_iter_next_invalid,
1129 list_store_teardown);
1130 g_test_add ("/ListStore/iter-children-invalid", ListStore, NULL,
1131 list_store_setup, list_store_test_iter_children_invalid,
1132 list_store_teardown);
1133 g_test_add ("/ListStore/iter-nth-child-invalid", ListStore, NULL,
1134 list_store_setup, list_store_test_iter_nth_child_invalid,
1135 list_store_teardown);
1136 g_test_add ("/ListStore/iter-parent-invalid", ListStore, NULL,
1137 list_store_setup, list_store_test_iter_parent_invalid,
1138 list_store_teardown);
1139}
1140

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