]> Pileus Git - ~andy/gtk/blob - gtk/tests/liststore.c
Change FSF Address
[~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 /* removal */
459 static void
460 list_store_test_remove_begin (ListStore     *fixture,
461                               gconstpointer  user_data)
462 {
463   int new_order[5] = { -1, 1, 2, 3, 4 };
464   GtkTreePath *path;
465   GtkTreeIter iter;
466
467   /* Remove node at 0 */
468   path = gtk_tree_path_new_from_indices (0, -1);
469   gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
470   gtk_tree_path_free (path);
471
472   g_assert (gtk_list_store_remove (fixture->store, &iter) == TRUE);
473   g_assert (!gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[0]));
474   g_assert (iters_equal (&iter, &fixture->iter[1]));
475
476   check_model (fixture, new_order, 0);
477 }
478
479 static void
480 list_store_test_remove_middle (ListStore     *fixture,
481                                gconstpointer  user_data)
482 {
483   int new_order[5] = { 0, 1, -1, 3, 4 };
484   GtkTreePath *path;
485   GtkTreeIter iter;
486
487   /* Remove node at 2 */
488   path = gtk_tree_path_new_from_indices (2, -1);
489   gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
490   gtk_tree_path_free (path);
491
492   g_assert (gtk_list_store_remove (fixture->store, &iter) == TRUE);
493   g_assert (!gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[2]));
494   g_assert (iters_equal (&iter, &fixture->iter[3]));
495
496   check_model (fixture, new_order, 2);
497 }
498
499 static void
500 list_store_test_remove_end (ListStore     *fixture,
501                             gconstpointer  user_data)
502 {
503   int new_order[5] = { 0, 1, 2, 3, -1 };
504   GtkTreePath *path;
505   GtkTreeIter iter;
506
507   /* Remove node at 4 */
508   path = gtk_tree_path_new_from_indices (4, -1);
509   gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
510   gtk_tree_path_free (path);
511
512   g_assert (gtk_list_store_remove (fixture->store, &iter) == FALSE);
513   g_assert (!gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[4]));
514
515   check_model (fixture, new_order, 4);
516 }
517
518 static void
519 list_store_test_clear (ListStore     *fixture,
520                        gconstpointer  user_data)
521 {
522   int i;
523
524   gtk_list_store_clear (fixture->store);
525
526   g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (fixture->store), NULL) == 0);
527
528   for (i = 0; i < 5; i++)
529     g_assert (!gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[i]));
530 }
531
532 /* reorder */
533
534 static void
535 list_store_test_reorder (ListStore     *fixture,
536                          gconstpointer  user_data)
537 {
538   int new_order[5] = { 4, 1, 0, 2, 3 };
539
540   gtk_list_store_reorder (fixture->store, new_order);
541   check_model (fixture, new_order, -1);
542 }
543
544 /* swapping */
545
546 static void
547 list_store_test_swap_begin (ListStore     *fixture,
548                             gconstpointer  user_data)
549 {
550   /* We swap nodes 0 and 1 at the beginning */
551   int new_order[5] = { 1, 0, 2, 3, 4 };
552
553   GtkTreeIter iter_a;
554   GtkTreeIter iter_b;
555
556   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "0"));
557   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "1"));
558
559   gtk_list_store_swap (fixture->store, &iter_a, &iter_b);
560   check_model (fixture, new_order, -1);
561 }
562
563 static void
564 list_store_test_swap_middle_next (ListStore     *fixture,
565                                   gconstpointer  user_data)
566 {
567   /* We swap nodes 2 and 3 in the middle that are next to each other */
568   int new_order[5] = { 0, 1, 3, 2, 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, "2"));
574   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "3"));
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_apart (ListStore     *fixture,
582                                    gconstpointer  user_data)
583 {
584   /* We swap nodes 1 and 3 in the middle that are apart from each other */
585   int new_order[5] = { 0, 3, 2, 1, 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, "1"));
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_end (ListStore     *fixture,
599                           gconstpointer  user_data)
600 {
601   /* We swap nodes 3 and 4 at the end */
602   int new_order[5] = { 0, 1, 2, 4, 3 };
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, "3"));
608   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "4"));
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_single (void)
616 {
617   GtkTreeIter iter;
618   GtkTreeIter iter_copy;
619   GtkListStore *store;
620
621   store = gtk_list_store_new (1, G_TYPE_INT);
622
623   /* Check if swap on a store with a single node does not corrupt
624    * the store.
625    */
626
627   gtk_list_store_append (store, &iter);
628   iter_copy = iter;
629
630   gtk_list_store_swap (store, &iter, &iter);
631   g_assert (iters_equal (&iter, &iter_copy));
632   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
633   g_assert (iters_equal (&iter, &iter_copy));
634
635   g_object_unref (store);
636 }
637
638 /* move after */
639
640 static void
641 list_store_test_move_after_from_start (ListStore     *fixture,
642                                        gconstpointer  user_data)
643 {
644   /* We move node 0 after 2 */
645   int new_order[5] = { 1, 2, 0, 3, 4 };
646
647   GtkTreeIter iter;
648   GtkTreeIter position;
649
650   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "0"));
651   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "2"));
652
653   gtk_list_store_move_after (fixture->store, &iter, &position);
654   check_model (fixture, new_order, -1);
655 }
656
657 static void
658 list_store_test_move_after_next (ListStore     *fixture,
659                                  gconstpointer  user_data)
660 {
661   /* We move node 2 after 3 */
662   int new_order[5] = { 0, 1, 3, 2, 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, "2"));
668   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "3"));
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_apart (ListStore     *fixture,
676                                   gconstpointer  user_data)
677 {
678   /* We move node 1 after 3 */
679   int new_order[5] = { 0, 2, 3, 1, 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, "1"));
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_end (ListStore     *fixture,
693                                 gconstpointer  user_data)
694 {
695   /* We move node 2 after 4 */
696   int new_order[5] = { 0, 1, 3, 4, 2 };
697
698   GtkTreeIter iter;
699   GtkTreeIter position;
700
701   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
702   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "4"));
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_from_end (ListStore     *fixture,
710                                      gconstpointer  user_data)
711 {
712   /* We move node 4 after 1 */
713   int new_order[5] = { 0, 1, 4, 2, 3 };
714
715   GtkTreeIter iter;
716   GtkTreeIter position;
717
718   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "4"));
719   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "1"));
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_change_ends (ListStore     *fixture,
727                                         gconstpointer  user_data)
728 {
729   /* We move 0 after 4, this will cause both the head and tail ends to
730    * change.
731    */
732   int new_order[5] = { 1, 2, 3, 4, 0 };
733
734   GtkTreeIter iter;
735   GtkTreeIter position;
736
737   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "0"));
738   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "4"));
739
740   gtk_list_store_move_after (fixture->store, &iter, &position);
741   check_model (fixture, new_order, -1);
742 }
743
744 static void
745 list_store_test_move_after_NULL (ListStore     *fixture,
746                                  gconstpointer  user_data)
747 {
748   /* We move node 2, NULL should prepend */
749   int new_order[5] = { 2, 0, 1, 3, 4 };
750
751   GtkTreeIter iter;
752
753   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
754
755   gtk_list_store_move_after (fixture->store, &iter, NULL);
756   check_model (fixture, new_order, -1);
757 }
758
759 static void
760 list_store_test_move_after_single (void)
761 {
762   GtkTreeIter iter;
763   GtkTreeIter iter_copy;
764   GtkListStore *store;
765
766   store = gtk_list_store_new (1, G_TYPE_INT);
767
768   /* Check if move-after on a store with a single node does not corrupt
769    * the store.
770    */
771
772   gtk_list_store_append (store, &iter);
773   iter_copy = iter;
774
775   gtk_list_store_move_after (store, &iter, NULL);
776   g_assert (iters_equal (&iter, &iter_copy));
777   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
778   g_assert (iters_equal (&iter, &iter_copy));
779
780   gtk_list_store_move_after (store, &iter, &iter);
781   g_assert (iters_equal (&iter, &iter_copy));
782   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
783   g_assert (iters_equal (&iter, &iter_copy));
784
785   g_object_unref (store);
786 }
787
788 /* move before */
789
790 static void
791 list_store_test_move_before_next (ListStore     *fixture,
792                                   gconstpointer  user_data)
793 {
794   /* We move node 3 before 2 */
795   int new_order[5] = { 0, 1, 3, 2, 4 };
796
797   GtkTreeIter iter;
798   GtkTreeIter position;
799
800   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "3"));
801   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "2"));
802
803   gtk_list_store_move_before (fixture->store, &iter, &position);
804   check_model (fixture, new_order, -1);
805 }
806
807 static void
808 list_store_test_move_before_apart (ListStore     *fixture,
809                                    gconstpointer  user_data)
810 {
811   /* We move node 1 before 3 */
812   int new_order[5] = { 0, 2, 1, 3, 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, "1"));
818   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "3"));
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_to_start (ListStore     *fixture,
826                                       gconstpointer  user_data)
827 {
828   /* We move node 2 before 0 */
829   int new_order[5] = { 2, 0, 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, "2"));
835   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "0"));
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_from_end (ListStore     *fixture,
843                                       gconstpointer  user_data)
844 {
845   /* We move node 4 before 2 (replace end) */
846   int new_order[5] = { 0, 1, 4, 2, 3 };
847
848   GtkTreeIter iter;
849   GtkTreeIter position;
850
851   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "4"));
852   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "2"));
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_change_ends (ListStore     *fixture,
860                                          gconstpointer  user_data)
861 {
862   /* We move node 4 before 0 */
863   int new_order[5] = { 4, 0, 1, 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, "0"));
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_NULL (ListStore     *fixture,
877                                   gconstpointer  user_data)
878 {
879   /* We move node 2, NULL should append */
880   int new_order[5] = { 0, 1, 3, 4, 2 };
881
882   GtkTreeIter iter;
883
884   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
885
886   gtk_list_store_move_before (fixture->store, &iter, NULL);
887   check_model (fixture, new_order, -1);
888 }
889
890 static void
891 list_store_test_move_before_single (void)
892 {
893   GtkTreeIter iter;
894   GtkTreeIter iter_copy;
895   GtkListStore *store;
896
897   store = gtk_list_store_new (1, G_TYPE_INT);
898
899   /* Check if move-before on a store with a single node does not corrupt
900    * the store.
901    */
902
903   gtk_list_store_append (store, &iter);
904   iter_copy = iter;
905
906   gtk_list_store_move_before (store, &iter, NULL);
907   g_assert (iters_equal (&iter, &iter_copy));
908   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
909   g_assert (iters_equal (&iter, &iter_copy));
910
911   gtk_list_store_move_before (store, &iter, &iter);
912   g_assert (iters_equal (&iter, &iter_copy));
913   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
914   g_assert (iters_equal (&iter, &iter_copy));
915
916   g_object_unref (store);
917 }
918
919
920 /* iter invalidation */
921
922 static void
923 list_store_test_iter_previous_invalid (ListStore     *fixture,
924                                        gconstpointer  user_data)
925 {
926   GtkTreeIter iter;
927
928   gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &iter);
929
930   g_assert (gtk_tree_model_iter_previous (GTK_TREE_MODEL (fixture->store),
931                                           &iter) == FALSE);
932   g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == FALSE);
933   g_assert (iter.stamp == 0);
934 }
935
936 static void
937 list_store_test_iter_next_invalid (ListStore     *fixture,
938                                    gconstpointer  user_data)
939 {
940   GtkTreePath *path;
941   GtkTreeIter iter;
942
943   path = gtk_tree_path_new_from_indices (4, -1);
944   gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
945   gtk_tree_path_free (path);
946
947   g_assert (gtk_tree_model_iter_next (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_children_invalid (ListStore     *fixture,
955                                        gconstpointer  user_data)
956 {
957   GtkTreeIter iter, child;
958
959   gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &iter);
960   g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == TRUE);
961
962   g_assert (gtk_tree_model_iter_children (GTK_TREE_MODEL (fixture->store),
963                                           &child, &iter) == FALSE);
964   g_assert (gtk_list_store_iter_is_valid (fixture->store, &child) == FALSE);
965   g_assert (child.stamp == 0);
966 }
967
968 static void
969 list_store_test_iter_nth_child_invalid (ListStore     *fixture,
970                                         gconstpointer  user_data)
971 {
972   GtkTreeIter iter, child;
973
974   gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &iter);
975   g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == TRUE);
976
977   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (fixture->store),
978                                            &child, &iter, 0) == FALSE);
979   g_assert (gtk_list_store_iter_is_valid (fixture->store, &child) == FALSE);
980   g_assert (child.stamp == 0);
981 }
982
983 static void
984 list_store_test_iter_parent_invalid (ListStore     *fixture,
985                                      gconstpointer  user_data)
986 {
987   GtkTreeIter iter, child;
988
989   gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &child);
990   g_assert (gtk_list_store_iter_is_valid (fixture->store, &child) == TRUE);
991
992   g_assert (gtk_tree_model_iter_parent (GTK_TREE_MODEL (fixture->store),
993                                         &iter, &child) == FALSE);
994   g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == FALSE);
995   g_assert (iter.stamp == 0);
996 }
997
998
999 /* main */
1000
1001 void
1002 register_list_store_tests (void)
1003 {
1004   /* insertion */
1005   g_test_add_func ("/ListStore/insert-high-values",
1006                    list_store_test_insert_high_values);
1007   g_test_add_func ("/ListStore/append",
1008                    list_store_test_append);
1009   g_test_add_func ("/ListStore/prepend",
1010                    list_store_test_prepend);
1011   g_test_add_func ("/ListStore/insert-after",
1012                    list_store_test_insert_after);
1013   g_test_add_func ("/ListStore/insert-after-NULL",
1014                    list_store_test_insert_after_NULL);
1015   g_test_add_func ("/ListStore/insert-before",
1016                    list_store_test_insert_before);
1017   g_test_add_func ("/ListStore/insert-before-NULL",
1018                    list_store_test_insert_before_NULL);
1019
1020   /* setting values (FIXME) */
1021
1022   /* removal */
1023   g_test_add ("/ListStore/remove-begin", ListStore, NULL,
1024               list_store_setup, list_store_test_remove_begin,
1025               list_store_teardown);
1026   g_test_add ("/ListStore/remove-middle", ListStore, NULL,
1027               list_store_setup, list_store_test_remove_middle,
1028               list_store_teardown);
1029   g_test_add ("/ListStore/remove-end", ListStore, NULL,
1030               list_store_setup, list_store_test_remove_end,
1031               list_store_teardown);
1032
1033   g_test_add ("/ListStore/clear", ListStore, NULL,
1034               list_store_setup, list_store_test_clear,
1035               list_store_teardown);
1036
1037   /* reordering */
1038   g_test_add ("/ListStore/reorder", ListStore, NULL,
1039               list_store_setup, list_store_test_reorder,
1040               list_store_teardown);
1041
1042   /* swapping */
1043   g_test_add ("/ListStore/swap-begin", ListStore, NULL,
1044               list_store_setup, list_store_test_swap_begin,
1045               list_store_teardown);
1046   g_test_add ("/ListStore/swap-middle-next", ListStore, NULL,
1047               list_store_setup, list_store_test_swap_middle_next,
1048               list_store_teardown);
1049   g_test_add ("/ListStore/swap-middle-apart", ListStore, NULL,
1050               list_store_setup, list_store_test_swap_middle_apart,
1051               list_store_teardown);
1052   g_test_add ("/ListStore/swap-end", ListStore, NULL,
1053               list_store_setup, list_store_test_swap_end,
1054               list_store_teardown);
1055   g_test_add_func ("/ListStore/swap-single",
1056                    list_store_test_swap_single);
1057
1058   /* moving */
1059   g_test_add ("/ListStore/move-after-from-start", ListStore, NULL,
1060               list_store_setup, list_store_test_move_after_from_start,
1061               list_store_teardown);
1062   g_test_add ("/ListStore/move-after-next", ListStore, NULL,
1063               list_store_setup, list_store_test_move_after_next,
1064               list_store_teardown);
1065   g_test_add ("/ListStore/move-after-apart", ListStore, NULL,
1066               list_store_setup, list_store_test_move_after_apart,
1067               list_store_teardown);
1068   g_test_add ("/ListStore/move-after-end", ListStore, NULL,
1069               list_store_setup, list_store_test_move_after_end,
1070               list_store_teardown);
1071   g_test_add ("/ListStore/move-after-from-end", ListStore, NULL,
1072               list_store_setup, list_store_test_move_after_from_end,
1073               list_store_teardown);
1074   g_test_add ("/ListStore/move-after-change-ends", ListStore, NULL,
1075               list_store_setup, list_store_test_move_after_change_ends,
1076               list_store_teardown);
1077   g_test_add ("/ListStore/move-after-NULL", ListStore, NULL,
1078               list_store_setup, list_store_test_move_after_NULL,
1079               list_store_teardown);
1080   g_test_add_func ("/ListStore/move-after-single",
1081                    list_store_test_move_after_single);
1082
1083   g_test_add ("/ListStore/move-before-next", ListStore, NULL,
1084               list_store_setup, list_store_test_move_before_next,
1085               list_store_teardown);
1086   g_test_add ("/ListStore/move-before-apart", ListStore, NULL,
1087               list_store_setup, list_store_test_move_before_apart,
1088               list_store_teardown);
1089   g_test_add ("/ListStore/move-before-to-start", ListStore, NULL,
1090               list_store_setup, list_store_test_move_before_to_start,
1091               list_store_teardown);
1092   g_test_add ("/ListStore/move-before-from-end", ListStore, NULL,
1093               list_store_setup, list_store_test_move_before_from_end,
1094               list_store_teardown);
1095   g_test_add ("/ListStore/move-before-change-ends", ListStore, NULL,
1096               list_store_setup, list_store_test_move_before_change_ends,
1097               list_store_teardown);
1098   g_test_add ("/ListStore/move-before-NULL", ListStore, NULL,
1099               list_store_setup, list_store_test_move_before_NULL,
1100               list_store_teardown);
1101   g_test_add_func ("/ListStore/move-before-single",
1102                    list_store_test_move_before_single);
1103
1104   /* iter invalidation */
1105   g_test_add ("/ListStore/iter-prev-invalid", ListStore, NULL,
1106               list_store_setup, list_store_test_iter_previous_invalid,
1107               list_store_teardown);
1108   g_test_add ("/ListStore/iter-next-invalid", ListStore, NULL,
1109               list_store_setup, list_store_test_iter_next_invalid,
1110               list_store_teardown);
1111   g_test_add ("/ListStore/iter-children-invalid", ListStore, NULL,
1112               list_store_setup, list_store_test_iter_children_invalid,
1113               list_store_teardown);
1114   g_test_add ("/ListStore/iter-nth-child-invalid", ListStore, NULL,
1115               list_store_setup, list_store_test_iter_nth_child_invalid,
1116               list_store_teardown);
1117   g_test_add ("/ListStore/iter-parent-invalid", ListStore, NULL,
1118               list_store_setup, list_store_test_iter_parent_invalid,
1119               list_store_teardown);
1120 }