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