]> Pileus Git - ~andy/gtk/blob - gtk/tests/liststore.c
filechooserbutton: Do not propagate state from the dialog unless it is active
[~andy/gtk] / gtk / tests / liststore.c
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
30 static inline gboolean
31 iters_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
45 static gboolean
46 iter_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  */
68 typedef struct
69 {
70   GtkTreeIter iter[5];
71   GtkListStore *store;
72 } ListStore;
73
74 static void
75 list_store_setup (ListStore     *fixture,
76                   gconstpointer  test_data)
77 {
78   int i;
79
80   fixture->store = gtk_list_store_new (1, G_TYPE_INT);
81
82   for (i = 0; i < 5; i++)
83     {
84       gtk_list_store_insert (fixture->store, &fixture->iter[i], i);
85       gtk_list_store_set (fixture->store, &fixture->iter[i], 0, i, -1);
86     }
87 }
88
89 static void
90 list_store_teardown (ListStore     *fixture,
91                      gconstpointer  test_data)
92 {
93   g_object_unref (fixture->store);
94 }
95
96 /*
97  * The actual tests.
98  */
99
100 static void
101 check_model (ListStore *fixture,
102              gint      *new_order,
103              gint       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, path);
127
128       g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter));
129       g_assert (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 */
138 static void
139 list_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 (1, G_TYPE_INT);
146
147   gtk_list_store_insert (store, &iter, 1234);
148   g_assert (gtk_list_store_iter_is_valid (store, &iter));
149   g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 1);
150   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
151   g_assert (iters_equal (&iter, &iter_copy));
152   g_assert (iter_position (store, &iter, 0));
153
154   gtk_list_store_insert (store, &iter2, 765);
155   g_assert (gtk_list_store_iter_is_valid (store, &iter2));
156   g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
157
158   /* Walk over the model */
159   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
160   g_assert (iters_equal (&iter, &iter_copy));
161   g_assert (iter_position (store, &iter, 0));
162
163   g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
164   g_assert (iters_equal (&iter2, &iter_copy));
165   g_assert (iter_position (store, &iter2, 1));
166
167   g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
168
169   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
170   g_assert (iters_equal (&iter2, &iter_copy));
171   g_assert (iter_position (store, &iter2, 1));
172
173   g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
174   g_assert (iters_equal (&iter, &iter_copy));
175   g_assert (iter_position (store, &iter, 0));
176
177   g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
178
179   g_object_unref (store);
180 }
181
182 static void
183 list_store_test_append (void)
184 {
185   GtkTreeIter iter, iter2;
186   GtkTreeIter iter_copy;
187   GtkListStore *store;
188
189   store = gtk_list_store_new (1, G_TYPE_INT);
190
191   gtk_list_store_append (store, &iter);
192   g_assert (gtk_list_store_iter_is_valid (store, &iter));
193   g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 1);
194   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
195   g_assert (iters_equal (&iter, &iter_copy));
196   g_assert (iter_position (store, &iter, 0));
197
198   gtk_list_store_append (store, &iter2);
199   g_assert (gtk_list_store_iter_is_valid (store, &iter2));
200   g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
201
202   /* Walk over the model */
203   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
204   g_assert (iters_equal (&iter, &iter_copy));
205   g_assert (iter_position (store, &iter, 0));
206
207   g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
208   g_assert (iters_equal (&iter2, &iter_copy));
209   g_assert (iter_position (store, &iter2, 1));
210
211   g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
212
213   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
214   g_assert (iters_equal (&iter2, &iter_copy));
215   g_assert (iter_position (store, &iter2, 1));
216
217   g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
218   g_assert (iters_equal (&iter, &iter_copy));
219   g_assert (iter_position (store, &iter, 0));
220
221   g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
222
223   g_object_unref (store);
224 }
225
226 static void
227 list_store_test_prepend (void)
228 {
229   GtkTreeIter iter, iter2;
230   GtkTreeIter iter_copy;
231   GtkListStore *store;
232
233   store = gtk_list_store_new (1, G_TYPE_INT);
234
235   gtk_list_store_prepend (store, &iter);
236   g_assert (gtk_list_store_iter_is_valid (store, &iter));
237   g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 1);
238   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
239   g_assert (iters_equal (&iter, &iter_copy));
240   g_assert (iter_position (store, &iter, 0));
241
242   gtk_list_store_prepend (store, &iter2);
243   g_assert (gtk_list_store_iter_is_valid (store, &iter2));
244   g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
245
246   /* Walk over the model */
247   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
248   g_assert (iters_equal (&iter2, &iter_copy));
249   g_assert (iter_position (store, &iter2, 0));
250
251   g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
252   g_assert (iters_equal (&iter, &iter_copy));
253   g_assert (iter_position (store, &iter, 1));
254
255   g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
256
257   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
258   g_assert (iters_equal (&iter, &iter_copy));
259   g_assert (iter_position (store, &iter, 1));
260
261   g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
262   g_assert (iters_equal (&iter2, &iter_copy));
263   g_assert (iter_position (store, &iter2, 0));
264
265   g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
266
267   g_object_unref (store);
268 }
269
270 static void
271 list_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 (1, G_TYPE_INT);
278
279   gtk_list_store_append (store, &iter);
280   gtk_list_store_append (store, &iter2);
281
282   gtk_list_store_insert_after (store, &iter3, &iter);
283   g_assert (gtk_list_store_iter_is_valid (store, &iter3));
284   g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 3);
285   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
286   g_assert (iters_equal (&iter3, &iter_copy));
287   g_assert (iter_position (store, &iter3, 1));
288
289   /* Walk over the model */
290   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
291   g_assert (iters_equal (&iter, &iter_copy));
292   g_assert (iter_position (store, &iter_copy, 0));
293
294   g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
295   g_assert (iters_equal (&iter3, &iter_copy));
296   g_assert (iter_position (store, &iter_copy, 1));
297
298   g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
299   g_assert (iters_equal (&iter2, &iter_copy));
300   g_assert (iter_position (store, &iter_copy, 2));
301
302   g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
303
304   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 2));
305   g_assert (iters_equal (&iter2, &iter_copy));
306   g_assert (iter_position (store, &iter2, 2));
307
308   g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
309   g_assert (iters_equal (&iter3, &iter_copy));
310   g_assert (iter_position (store, &iter3, 1));
311
312   g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
313   g_assert (iters_equal (&iter, &iter_copy));
314   g_assert (iter_position (store, &iter, 0));
315
316   g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
317
318   g_object_unref (store);
319 }
320
321 static void
322 list_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 (1, G_TYPE_INT);
329
330   gtk_list_store_append (store, &iter);
331
332   /* move_after NULL is basically a prepend */
333   gtk_list_store_insert_after (store, &iter2, NULL);
334   g_assert (gtk_list_store_iter_is_valid (store, &iter2));
335   g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
336
337   /* Walk over the model */
338   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
339   g_assert (iters_equal (&iter2, &iter_copy));
340   g_assert (iter_position (store, &iter2, 0));
341
342   g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
343   g_assert (iters_equal (&iter, &iter_copy));
344   g_assert (iter_position (store, &iter, 1));
345
346   g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
347
348   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 0));
349   g_assert (iters_equal (&iter2, &iter_copy));
350
351   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
352   g_assert (iters_equal (&iter, &iter_copy));
353   g_assert (iter_position (store, &iter, 1));
354
355   g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
356   g_assert (iters_equal (&iter2, &iter_copy));
357   g_assert (iter_position (store, &iter2, 0));
358
359   g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
360
361   g_object_unref (store);
362 }
363
364 static void
365 list_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 (1, G_TYPE_INT);
372
373   gtk_list_store_append (store, &iter);
374   gtk_list_store_append (store, &iter2);
375
376   gtk_list_store_insert_before (store, &iter3, &iter2);
377   g_assert (gtk_list_store_iter_is_valid (store, &iter3));
378   g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 3);
379   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
380   g_assert (iters_equal (&iter3, &iter_copy));
381   g_assert (iter_position (store, &iter3, 1));
382
383   /* Walk over the model */
384   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
385   g_assert (iters_equal (&iter, &iter_copy));
386   g_assert (iter_position (store, &iter_copy, 0));
387
388   g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
389   g_assert (iters_equal (&iter3, &iter_copy));
390   g_assert (iter_position (store, &iter_copy, 1));
391
392   g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
393   g_assert (iters_equal (&iter2, &iter_copy));
394   g_assert (iter_position (store, &iter_copy, 2));
395
396   g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
397
398   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
399   g_assert (iters_equal (&iter3, &iter_copy));
400
401   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 2));
402   g_assert (iters_equal (&iter2, &iter_copy));
403   g_assert (iter_position (store, &iter2, 2));
404
405   g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
406   g_assert (iters_equal (&iter3, &iter_copy));
407   g_assert (iter_position (store, &iter3, 1));
408
409   g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
410   g_assert (iters_equal (&iter, &iter_copy));
411   g_assert (iter_position (store, &iter, 0));
412
413   g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
414
415   g_object_unref (store);
416 }
417
418 static void
419 list_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 (1, G_TYPE_INT);
426
427   gtk_list_store_append (store, &iter);
428
429   /* move_before NULL is basically an append */
430   gtk_list_store_insert_before (store, &iter2, NULL);
431   g_assert (gtk_list_store_iter_is_valid (store, &iter2));
432   g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
433
434   /* Walk over the model */
435   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
436   g_assert (iters_equal (&iter, &iter_copy));
437   g_assert (iter_position (store, &iter, 0));
438
439   g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
440   g_assert (iters_equal (&iter2, &iter_copy));
441   g_assert (iter_position (store, &iter2, 1));
442
443   g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
444
445   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
446   g_assert (iters_equal (&iter2, &iter_copy));
447   g_assert (iter_position (store, &iter2, 1));
448
449   g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
450   g_assert (iters_equal (&iter, &iter_copy));
451   g_assert (iter_position (store, &iter, 0));
452
453   g_assert (!gtk_tree_model_iter_previous (GTK_TREE_MODEL (store), &iter_copy));
454
455   g_object_unref (store);
456 }
457
458 /* setting values */
459 static void
460 list_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 (1, G_TYPE_LONG);
468   gtk_list_store_append (store, &iter);
469
470   g_value_init (&value, G_TYPE_INT);
471   g_value_set_int (&value, 42);
472   gtk_list_store_set_value (store, &iter, 0, &value);
473 }
474
475 /* removal */
476 static void
477 list_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 (0, -1);
486   gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
487   gtk_tree_path_free (path);
488
489   g_assert (gtk_list_store_remove (fixture->store, &iter) == TRUE);
490   g_assert (!gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[0]));
491   g_assert (iters_equal (&iter, &fixture->iter[1]));
492
493   check_model (fixture, new_order, 0);
494 }
495
496 static void
497 list_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 (2, -1);
506   gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
507   gtk_tree_path_free (path);
508
509   g_assert (gtk_list_store_remove (fixture->store, &iter) == TRUE);
510   g_assert (!gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[2]));
511   g_assert (iters_equal (&iter, &fixture->iter[3]));
512
513   check_model (fixture, new_order, 2);
514 }
515
516 static void
517 list_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 (4, -1);
526   gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
527   gtk_tree_path_free (path);
528
529   g_assert (gtk_list_store_remove (fixture->store, &iter) == FALSE);
530   g_assert (!gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[4]));
531
532   check_model (fixture, new_order, 4);
533 }
534
535 static void
536 list_store_test_clear (ListStore     *fixture,
537                        gconstpointer  user_data)
538 {
539   int i;
540
541   gtk_list_store_clear (fixture->store);
542
543   g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (fixture->store), NULL) == 0);
544
545   for (i = 0; i < 5; i++)
546     g_assert (!gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[i]));
547 }
548
549 /* reorder */
550
551 static void
552 list_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 (fixture->store, new_order);
558   check_model (fixture, new_order, -1);
559 }
560
561 /* swapping */
562
563 static void
564 list_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 (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "0"));
574   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "1"));
575
576   gtk_list_store_swap (fixture->store, &iter_a, &iter_b);
577   check_model (fixture, new_order, -1);
578 }
579
580 static void
581 list_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 (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "2"));
591   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "3"));
592
593   gtk_list_store_swap (fixture->store, &iter_a, &iter_b);
594   check_model (fixture, new_order, -1);
595 }
596
597 static void
598 list_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 (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "1"));
608   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "3"));
609
610   gtk_list_store_swap (fixture->store, &iter_a, &iter_b);
611   check_model (fixture, new_order, -1);
612 }
613
614 static void
615 list_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 (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "3"));
625   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "4"));
626
627   gtk_list_store_swap (fixture->store, &iter_a, &iter_b);
628   check_model (fixture, new_order, -1);
629 }
630
631 static void
632 list_store_test_swap_single (void)
633 {
634   GtkTreeIter iter;
635   GtkTreeIter iter_copy;
636   GtkListStore *store;
637
638   store = gtk_list_store_new (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 (store, &iter);
645   iter_copy = iter;
646
647   gtk_list_store_swap (store, &iter, &iter);
648   g_assert (iters_equal (&iter, &iter_copy));
649   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
650   g_assert (iters_equal (&iter, &iter_copy));
651
652   g_object_unref (store);
653 }
654
655 /* move after */
656
657 static void
658 list_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 (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "0"));
668   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "2"));
669
670   gtk_list_store_move_after (fixture->store, &iter, &position);
671   check_model (fixture, new_order, -1);
672 }
673
674 static void
675 list_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 (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
685   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "3"));
686
687   gtk_list_store_move_after (fixture->store, &iter, &position);
688   check_model (fixture, new_order, -1);
689 }
690
691 static void
692 list_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 (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "1"));
702   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "3"));
703
704   gtk_list_store_move_after (fixture->store, &iter, &position);
705   check_model (fixture, new_order, -1);
706 }
707
708 static void
709 list_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 (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
719   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "4"));
720
721   gtk_list_store_move_after (fixture->store, &iter, &position);
722   check_model (fixture, new_order, -1);
723 }
724
725 static void
726 list_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 (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "4"));
736   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "1"));
737
738   gtk_list_store_move_after (fixture->store, &iter, &position);
739   check_model (fixture, new_order, -1);
740 }
741
742 static void
743 list_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 (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "0"));
755   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "4"));
756
757   gtk_list_store_move_after (fixture->store, &iter, &position);
758   check_model (fixture, new_order, -1);
759 }
760
761 static void
762 list_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 (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
771
772   gtk_list_store_move_after (fixture->store, &iter, NULL);
773   check_model (fixture, new_order, -1);
774 }
775
776 static void
777 list_store_test_move_after_single (void)
778 {
779   GtkTreeIter iter;
780   GtkTreeIter iter_copy;
781   GtkListStore *store;
782
783   store = gtk_list_store_new (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 (store, &iter);
790   iter_copy = iter;
791
792   gtk_list_store_move_after (store, &iter, NULL);
793   g_assert (iters_equal (&iter, &iter_copy));
794   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
795   g_assert (iters_equal (&iter, &iter_copy));
796
797   gtk_list_store_move_after (store, &iter, &iter);
798   g_assert (iters_equal (&iter, &iter_copy));
799   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
800   g_assert (iters_equal (&iter, &iter_copy));
801
802   g_object_unref (store);
803 }
804
805 /* move before */
806
807 static void
808 list_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 (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "3"));
818   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "2"));
819
820   gtk_list_store_move_before (fixture->store, &iter, &position);
821   check_model (fixture, new_order, -1);
822 }
823
824 static void
825 list_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 (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "1"));
835   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "3"));
836
837   gtk_list_store_move_before (fixture->store, &iter, &position);
838   check_model (fixture, new_order, -1);
839 }
840
841 static void
842 list_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 (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
852   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "0"));
853
854   gtk_list_store_move_before (fixture->store, &iter, &position);
855   check_model (fixture, new_order, -1);
856 }
857
858 static void
859 list_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 (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "4"));
869   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "2"));
870
871   gtk_list_store_move_before (fixture->store, &iter, &position);
872   check_model (fixture, new_order, -1);
873 }
874
875 static void
876 list_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 (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "4"));
886   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "0"));
887
888   gtk_list_store_move_before (fixture->store, &iter, &position);
889   check_model (fixture, new_order, -1);
890 }
891
892 static void
893 list_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 (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
902
903   gtk_list_store_move_before (fixture->store, &iter, NULL);
904   check_model (fixture, new_order, -1);
905 }
906
907 static void
908 list_store_test_move_before_single (void)
909 {
910   GtkTreeIter iter;
911   GtkTreeIter iter_copy;
912   GtkListStore *store;
913
914   store = gtk_list_store_new (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 (store, &iter);
921   iter_copy = iter;
922
923   gtk_list_store_move_before (store, &iter, NULL);
924   g_assert (iters_equal (&iter, &iter_copy));
925   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
926   g_assert (iters_equal (&iter, &iter_copy));
927
928   gtk_list_store_move_before (store, &iter, &iter);
929   g_assert (iters_equal (&iter, &iter_copy));
930   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
931   g_assert (iters_equal (&iter, &iter_copy));
932
933   g_object_unref (store);
934 }
935
936
937 /* iter invalidation */
938
939 static void
940 list_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);
946
947   g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (fixture->store),
948                                           &iter) == FALSE);
949   g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == FALSE);
950   g_assert (iter.stamp == 0);
951 }
952
953 static void
954 list_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 (4, -1);
961   gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
962   gtk_tree_path_free (path);
963
964   g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store),
965                                       &iter) == FALSE);
966   g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == FALSE);
967   g_assert (iter.stamp == 0);
968 }
969
970 static void
971 list_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);
977   g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == TRUE);
978
979   g_assert (gtk_tree_model_iter_children (GTK_TREE_MODEL (fixture->store),
980                                           &child, &iter) == FALSE);
981   g_assert (gtk_list_store_iter_is_valid (fixture->store, &child) == FALSE);
982   g_assert (child.stamp == 0);
983 }
984
985 static void
986 list_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);
992   g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == TRUE);
993
994   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (fixture->store),
995                                            &child, &iter, 0) == FALSE);
996   g_assert (gtk_list_store_iter_is_valid (fixture->store, &child) == FALSE);
997   g_assert (child.stamp == 0);
998 }
999
1000 static void
1001 list_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), &child);
1007   g_assert (gtk_list_store_iter_is_valid (fixture->store, &child) == TRUE);
1008
1009   g_assert (gtk_tree_model_iter_parent (GTK_TREE_MODEL (fixture->store),
1010                                         &iter, &child) == FALSE);
1011   g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == FALSE);
1012   g_assert (iter.stamp == 0);
1013 }
1014
1015
1016 /* main */
1017
1018 void
1019 register_list_store_tests (void)
1020 {
1021   /* insertion */
1022   g_test_add_func ("/ListStore/insert-high-values",
1023                    list_store_test_insert_high_values);
1024   g_test_add_func ("/ListStore/append",
1025                    list_store_test_append);
1026   g_test_add_func ("/ListStore/prepend",
1027                    list_store_test_prepend);
1028   g_test_add_func ("/ListStore/insert-after",
1029                    list_store_test_insert_after);
1030   g_test_add_func ("/ListStore/insert-after-NULL",
1031                    list_store_test_insert_after_NULL);
1032   g_test_add_func ("/ListStore/insert-before",
1033                    list_store_test_insert_before);
1034   g_test_add_func ("/ListStore/insert-before-NULL",
1035                    list_store_test_insert_before_NULL);
1036
1037   /* setting values (FIXME) */
1038   g_test_add_func ("/ListStore/set-gvalue-to-transform",
1039                    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 ("/ListStore/swap-single",
1075                    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 ("/ListStore/move-after-single",
1100                    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 ("/ListStore/move-before-single",
1121                    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 }