]> Pileus Git - ~andy/gtk/blob - gtk/tests/liststore.c
Add length to gtk_tree_path_get_indices
[~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 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, NULL)[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
172   g_object_unref (store);
173 }
174
175 static void
176 list_store_test_append (void)
177 {
178   GtkTreeIter iter, iter2;
179   GtkTreeIter iter_copy;
180   GtkListStore *store;
181
182   store = gtk_list_store_new (1, G_TYPE_INT);
183
184   gtk_list_store_append (store, &iter);
185   g_assert (gtk_list_store_iter_is_valid (store, &iter));
186   g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 1);
187   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
188   g_assert (iters_equal (&iter, &iter_copy));
189   g_assert (iter_position (store, &iter, 0));
190
191   gtk_list_store_append (store, &iter2);
192   g_assert (gtk_list_store_iter_is_valid (store, &iter2));
193   g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
194
195   /* Walk over the model */
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   g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
201   g_assert (iters_equal (&iter2, &iter_copy));
202   g_assert (iter_position (store, &iter2, 1));
203
204   g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
205
206   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
207   g_assert (iters_equal (&iter2, &iter_copy));
208
209   g_object_unref (store);
210 }
211
212 static void
213 list_store_test_prepend (void)
214 {
215   GtkTreeIter iter, iter2;
216   GtkTreeIter iter_copy;
217   GtkListStore *store;
218
219   store = gtk_list_store_new (1, G_TYPE_INT);
220
221   gtk_list_store_prepend (store, &iter);
222   g_assert (gtk_list_store_iter_is_valid (store, &iter));
223   g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 1);
224   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
225   g_assert (iters_equal (&iter, &iter_copy));
226   g_assert (iter_position (store, &iter, 0));
227
228   gtk_list_store_prepend (store, &iter2);
229   g_assert (gtk_list_store_iter_is_valid (store, &iter2));
230   g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
231
232   /* Walk over the model */
233   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
234   g_assert (iters_equal (&iter2, &iter_copy));
235   g_assert (iter_position (store, &iter2, 0));
236
237   g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
238   g_assert (iters_equal (&iter, &iter_copy));
239   g_assert (iter_position (store, &iter, 1));
240
241   g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
242
243   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
244   g_assert (iters_equal (&iter, &iter_copy));
245
246   g_object_unref (store);
247 }
248
249 static void
250 list_store_test_insert_after (void)
251 {
252   GtkTreeIter iter, iter2, iter3;
253   GtkTreeIter iter_copy;
254   GtkListStore *store;
255
256   store = gtk_list_store_new (1, G_TYPE_INT);
257
258   gtk_list_store_append (store, &iter);
259   gtk_list_store_append (store, &iter2);
260
261   gtk_list_store_insert_after (store, &iter3, &iter);
262   g_assert (gtk_list_store_iter_is_valid (store, &iter3));
263   g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 3);
264   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
265   g_assert (iters_equal (&iter3, &iter_copy));
266   g_assert (iter_position (store, &iter3, 1));
267
268   /* Walk over the model */
269   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
270   g_assert (iters_equal (&iter, &iter_copy));
271   g_assert (iter_position (store, &iter_copy, 0));
272
273   g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
274   g_assert (iters_equal (&iter3, &iter_copy));
275   g_assert (iter_position (store, &iter_copy, 1));
276
277   g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
278   g_assert (iters_equal (&iter2, &iter_copy));
279   g_assert (iter_position (store, &iter_copy, 2));
280
281   g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
282
283   g_object_unref (store);
284 }
285
286 static void
287 list_store_test_insert_after_NULL (void)
288 {
289   GtkTreeIter iter, iter2;
290   GtkTreeIter iter_copy;
291   GtkListStore *store;
292
293   store = gtk_list_store_new (1, G_TYPE_INT);
294
295   gtk_list_store_append (store, &iter);
296
297   /* move_after NULL is basically a prepend */
298   gtk_list_store_insert_after (store, &iter2, NULL);
299   g_assert (gtk_list_store_iter_is_valid (store, &iter2));
300   g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
301
302   /* Walk over the model */
303   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
304   g_assert (iters_equal (&iter2, &iter_copy));
305   g_assert (iter_position (store, &iter2, 0));
306
307   g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
308   g_assert (iters_equal (&iter, &iter_copy));
309   g_assert (iter_position (store, &iter, 1));
310
311   g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
312
313   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 0));
314   g_assert (iters_equal (&iter2, &iter_copy));
315
316   g_object_unref (store);
317 }
318
319 static void
320 list_store_test_insert_before (void)
321 {
322   GtkTreeIter iter, iter2, iter3;
323   GtkTreeIter iter_copy;
324   GtkListStore *store;
325
326   store = gtk_list_store_new (1, G_TYPE_INT);
327
328   gtk_list_store_append (store, &iter);
329   gtk_list_store_append (store, &iter2);
330
331   gtk_list_store_insert_before (store, &iter3, &iter2);
332   g_assert (gtk_list_store_iter_is_valid (store, &iter3));
333   g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 3);
334   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
335   g_assert (iters_equal (&iter3, &iter_copy));
336   g_assert (iter_position (store, &iter3, 1));
337
338   /* Walk over the model */
339   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
340   g_assert (iters_equal (&iter, &iter_copy));
341   g_assert (iter_position (store, &iter_copy, 0));
342
343   g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
344   g_assert (iters_equal (&iter3, &iter_copy));
345   g_assert (iter_position (store, &iter_copy, 1));
346
347   g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
348   g_assert (iters_equal (&iter2, &iter_copy));
349   g_assert (iter_position (store, &iter_copy, 2));
350
351   g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &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 (&iter3, &iter_copy));
355
356   g_object_unref (store);
357 }
358
359 static void
360 list_store_test_insert_before_NULL (void)
361 {
362   GtkTreeIter iter, iter2;
363   GtkTreeIter iter_copy;
364   GtkListStore *store;
365
366   store = gtk_list_store_new (1, G_TYPE_INT);
367
368   gtk_list_store_append (store, &iter);
369
370   /* move_before NULL is basically an append */
371   gtk_list_store_insert_before (store, &iter2, NULL);
372   g_assert (gtk_list_store_iter_is_valid (store, &iter2));
373   g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) == 2);
374
375   /* Walk over the model */
376   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter_copy));
377   g_assert (iters_equal (&iter, &iter_copy));
378   g_assert (iter_position (store, &iter, 0));
379
380   g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
381   g_assert (iters_equal (&iter2, &iter_copy));
382   g_assert (iter_position (store, &iter2, 1));
383
384   g_assert (!gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter_copy));
385
386   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (store), &iter_copy, NULL, 1));
387   g_assert (iters_equal (&iter2, &iter_copy));
388
389   g_object_unref (store);
390 }
391
392 /* removal */
393 static void
394 list_store_test_remove_begin (ListStore     *fixture,
395                               gconstpointer  user_data)
396 {
397   int new_order[5] = { -1, 1, 2, 3, 4 };
398   GtkTreePath *path;
399   GtkTreeIter iter;
400
401   /* Remove node at 0 */
402   path = gtk_tree_path_new_from_indices (0, -1);
403   gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
404   gtk_tree_path_free (path);
405
406   g_assert (gtk_list_store_remove (fixture->store, &iter) == TRUE);
407   g_assert (!gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[0]));
408   g_assert (iters_equal (&iter, &fixture->iter[1]));
409
410   check_model (fixture, new_order, 0);
411 }
412
413 static void
414 list_store_test_remove_middle (ListStore     *fixture,
415                                gconstpointer  user_data)
416 {
417   int new_order[5] = { 0, 1, -1, 3, 4 };
418   GtkTreePath *path;
419   GtkTreeIter iter;
420
421   /* Remove node at 2 */
422   path = gtk_tree_path_new_from_indices (2, -1);
423   gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
424   gtk_tree_path_free (path);
425
426   g_assert (gtk_list_store_remove (fixture->store, &iter) == TRUE);
427   g_assert (!gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[2]));
428   g_assert (iters_equal (&iter, &fixture->iter[3]));
429
430   check_model (fixture, new_order, 2);
431 }
432
433 static void
434 list_store_test_remove_end (ListStore     *fixture,
435                             gconstpointer  user_data)
436 {
437   int new_order[5] = { 0, 1, 2, 3, -1 };
438   GtkTreePath *path;
439   GtkTreeIter iter;
440
441   /* Remove node at 4 */
442   path = gtk_tree_path_new_from_indices (4, -1);
443   gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
444   gtk_tree_path_free (path);
445
446   g_assert (gtk_list_store_remove (fixture->store, &iter) == FALSE);
447   g_assert (!gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[4]));
448
449   check_model (fixture, new_order, 4);
450 }
451
452 static void
453 list_store_test_clear (ListStore     *fixture,
454                        gconstpointer  user_data)
455 {
456   int i;
457
458   gtk_list_store_clear (fixture->store);
459
460   g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (fixture->store), NULL) == 0);
461
462   for (i = 0; i < 5; i++)
463     g_assert (!gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[i]));
464 }
465
466 /* reorder */
467
468 static void
469 list_store_test_reorder (ListStore     *fixture,
470                          gconstpointer  user_data)
471 {
472   int new_order[5] = { 4, 1, 0, 2, 3 };
473
474   gtk_list_store_reorder (fixture->store, new_order);
475   check_model (fixture, new_order, -1);
476 }
477
478 /* swapping */
479
480 static void
481 list_store_test_swap_begin (ListStore     *fixture,
482                             gconstpointer  user_data)
483 {
484   /* We swap nodes 0 and 1 at the beginning */
485   int new_order[5] = { 1, 0, 2, 3, 4 };
486
487   GtkTreeIter iter_a;
488   GtkTreeIter iter_b;
489
490   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "0"));
491   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "1"));
492
493   gtk_list_store_swap (fixture->store, &iter_a, &iter_b);
494   check_model (fixture, new_order, -1);
495 }
496
497 static void
498 list_store_test_swap_middle_next (ListStore     *fixture,
499                                   gconstpointer  user_data)
500 {
501   /* We swap nodes 2 and 3 in the middle that are next to each other */
502   int new_order[5] = { 0, 1, 3, 2, 4 };
503
504   GtkTreeIter iter_a;
505   GtkTreeIter iter_b;
506
507   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "2"));
508   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "3"));
509
510   gtk_list_store_swap (fixture->store, &iter_a, &iter_b);
511   check_model (fixture, new_order, -1);
512 }
513
514 static void
515 list_store_test_swap_middle_apart (ListStore     *fixture,
516                                    gconstpointer  user_data)
517 {
518   /* We swap nodes 1 and 3 in the middle that are apart from each other */
519   int new_order[5] = { 0, 3, 2, 1, 4 };
520
521   GtkTreeIter iter_a;
522   GtkTreeIter iter_b;
523
524   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "1"));
525   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "3"));
526
527   gtk_list_store_swap (fixture->store, &iter_a, &iter_b);
528   check_model (fixture, new_order, -1);
529 }
530
531 static void
532 list_store_test_swap_end (ListStore     *fixture,
533                           gconstpointer  user_data)
534 {
535   /* We swap nodes 3 and 4 at the end */
536   int new_order[5] = { 0, 1, 2, 4, 3 };
537
538   GtkTreeIter iter_a;
539   GtkTreeIter iter_b;
540
541   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "3"));
542   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "4"));
543
544   gtk_list_store_swap (fixture->store, &iter_a, &iter_b);
545   check_model (fixture, new_order, -1);
546 }
547
548 static void
549 list_store_test_swap_single (void)
550 {
551   GtkTreeIter iter;
552   GtkTreeIter iter_copy;
553   GtkListStore *store;
554
555   store = gtk_list_store_new (1, G_TYPE_INT);
556
557   /* Check if swap on a store with a single node does not corrupt
558    * the store.
559    */
560
561   gtk_list_store_append (store, &iter);
562   iter_copy = iter;
563
564   gtk_list_store_swap (store, &iter, &iter);
565   g_assert (iters_equal (&iter, &iter_copy));
566   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
567   g_assert (iters_equal (&iter, &iter_copy));
568
569   g_object_unref (store);
570 }
571
572 /* move after */
573
574 static void
575 list_store_test_move_after_from_start (ListStore     *fixture,
576                                        gconstpointer  user_data)
577 {
578   /* We move node 0 after 2 */
579   int new_order[5] = { 1, 2, 0, 3, 4 };
580
581   GtkTreeIter iter;
582   GtkTreeIter position;
583
584   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "0"));
585   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "2"));
586
587   gtk_list_store_move_after (fixture->store, &iter, &position);
588   check_model (fixture, new_order, -1);
589 }
590
591 static void
592 list_store_test_move_after_next (ListStore     *fixture,
593                                  gconstpointer  user_data)
594 {
595   /* We move node 2 after 3 */
596   int new_order[5] = { 0, 1, 3, 2, 4 };
597
598   GtkTreeIter iter;
599   GtkTreeIter position;
600
601   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
602   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "3"));
603
604   gtk_list_store_move_after (fixture->store, &iter, &position);
605   check_model (fixture, new_order, -1);
606 }
607
608 static void
609 list_store_test_move_after_apart (ListStore     *fixture,
610                                   gconstpointer  user_data)
611 {
612   /* We move node 1 after 3 */
613   int new_order[5] = { 0, 2, 3, 1, 4 };
614
615   GtkTreeIter iter;
616   GtkTreeIter position;
617
618   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "1"));
619   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "3"));
620
621   gtk_list_store_move_after (fixture->store, &iter, &position);
622   check_model (fixture, new_order, -1);
623 }
624
625 static void
626 list_store_test_move_after_end (ListStore     *fixture,
627                                 gconstpointer  user_data)
628 {
629   /* We move node 2 after 4 */
630   int new_order[5] = { 0, 1, 3, 4, 2 };
631
632   GtkTreeIter iter;
633   GtkTreeIter position;
634
635   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
636   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "4"));
637
638   gtk_list_store_move_after (fixture->store, &iter, &position);
639   check_model (fixture, new_order, -1);
640 }
641
642 static void
643 list_store_test_move_after_from_end (ListStore     *fixture,
644                                      gconstpointer  user_data)
645 {
646   /* We move node 4 after 1 */
647   int new_order[5] = { 0, 1, 4, 2, 3 };
648
649   GtkTreeIter iter;
650   GtkTreeIter position;
651
652   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "4"));
653   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "1"));
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_change_ends (ListStore     *fixture,
661                                         gconstpointer  user_data)
662 {
663   /* We move 0 after 4, this will cause both the head and tail ends to
664    * change.
665    */
666   int new_order[5] = { 1, 2, 3, 4, 0 };
667
668   GtkTreeIter iter;
669   GtkTreeIter position;
670
671   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "0"));
672   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "4"));
673
674   gtk_list_store_move_after (fixture->store, &iter, &position);
675   check_model (fixture, new_order, -1);
676 }
677
678 static void
679 list_store_test_move_after_NULL (ListStore     *fixture,
680                                  gconstpointer  user_data)
681 {
682   /* We move node 2, NULL should prepend */
683   int new_order[5] = { 2, 0, 1, 3, 4 };
684
685   GtkTreeIter iter;
686
687   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
688
689   gtk_list_store_move_after (fixture->store, &iter, NULL);
690   check_model (fixture, new_order, -1);
691 }
692
693 static void
694 list_store_test_move_after_single (void)
695 {
696   GtkTreeIter iter;
697   GtkTreeIter iter_copy;
698   GtkListStore *store;
699
700   store = gtk_list_store_new (1, G_TYPE_INT);
701
702   /* Check if move-after on a store with a single node does not corrupt
703    * the store.
704    */
705
706   gtk_list_store_append (store, &iter);
707   iter_copy = iter;
708
709   gtk_list_store_move_after (store, &iter, NULL);
710   g_assert (iters_equal (&iter, &iter_copy));
711   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
712   g_assert (iters_equal (&iter, &iter_copy));
713
714   gtk_list_store_move_after (store, &iter, &iter);
715   g_assert (iters_equal (&iter, &iter_copy));
716   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
717   g_assert (iters_equal (&iter, &iter_copy));
718
719   g_object_unref (store);
720 }
721
722 /* move before */
723
724 static void
725 list_store_test_move_before_next (ListStore     *fixture,
726                                   gconstpointer  user_data)
727 {
728   /* We move node 3 before 2 */
729   int new_order[5] = { 0, 1, 3, 2, 4 };
730
731   GtkTreeIter iter;
732   GtkTreeIter position;
733
734   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "3"));
735   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "2"));
736
737   gtk_list_store_move_before (fixture->store, &iter, &position);
738   check_model (fixture, new_order, -1);
739 }
740
741 static void
742 list_store_test_move_before_apart (ListStore     *fixture,
743                                    gconstpointer  user_data)
744 {
745   /* We move node 1 before 3 */
746   int new_order[5] = { 0, 2, 1, 3, 4 };
747
748   GtkTreeIter iter;
749   GtkTreeIter position;
750
751   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "1"));
752   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "3"));
753
754   gtk_list_store_move_before (fixture->store, &iter, &position);
755   check_model (fixture, new_order, -1);
756 }
757
758 static void
759 list_store_test_move_before_to_start (ListStore     *fixture,
760                                       gconstpointer  user_data)
761 {
762   /* We move node 2 before 0 */
763   int new_order[5] = { 2, 0, 1, 3, 4 };
764
765   GtkTreeIter iter;
766   GtkTreeIter position;
767
768   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
769   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "0"));
770
771   gtk_list_store_move_before (fixture->store, &iter, &position);
772   check_model (fixture, new_order, -1);
773 }
774
775 static void
776 list_store_test_move_before_from_end (ListStore     *fixture,
777                                       gconstpointer  user_data)
778 {
779   /* We move node 4 before 2 (replace end) */
780   int new_order[5] = { 0, 1, 4, 2, 3 };
781
782   GtkTreeIter iter;
783   GtkTreeIter position;
784
785   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "4"));
786   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "2"));
787
788   gtk_list_store_move_before (fixture->store, &iter, &position);
789   check_model (fixture, new_order, -1);
790 }
791
792 static void
793 list_store_test_move_before_change_ends (ListStore     *fixture,
794                                          gconstpointer  user_data)
795 {
796   /* We move node 4 before 0 */
797   int new_order[5] = { 4, 0, 1, 2, 3 };
798
799   GtkTreeIter iter;
800   GtkTreeIter position;
801
802   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "4"));
803   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "0"));
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_NULL (ListStore     *fixture,
811                                   gconstpointer  user_data)
812 {
813   /* We move node 2, NULL should append */
814   int new_order[5] = { 0, 1, 3, 4, 2 };
815
816   GtkTreeIter iter;
817
818   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
819
820   gtk_list_store_move_before (fixture->store, &iter, NULL);
821   check_model (fixture, new_order, -1);
822 }
823
824 static void
825 list_store_test_move_before_single (void)
826 {
827   GtkTreeIter iter;
828   GtkTreeIter iter_copy;
829   GtkListStore *store;
830
831   store = gtk_list_store_new (1, G_TYPE_INT);
832
833   /* Check if move-before on a store with a single node does not corrupt
834    * the store.
835    */
836
837   gtk_list_store_append (store, &iter);
838   iter_copy = iter;
839
840   gtk_list_store_move_before (store, &iter, NULL);
841   g_assert (iters_equal (&iter, &iter_copy));
842   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
843   g_assert (iters_equal (&iter, &iter_copy));
844
845   gtk_list_store_move_before (store, &iter, &iter);
846   g_assert (iters_equal (&iter, &iter_copy));
847   g_assert (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter));
848   g_assert (iters_equal (&iter, &iter_copy));
849
850   g_object_unref (store);
851 }
852
853
854 /* iter invalidation */
855
856 static void
857 list_store_test_iter_next_invalid (ListStore     *fixture,
858                                    gconstpointer  user_data)
859 {
860   GtkTreePath *path;
861   GtkTreeIter iter;
862
863   path = gtk_tree_path_new_from_indices (4, -1);
864   gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
865   gtk_tree_path_free (path);
866
867   g_assert (gtk_tree_model_iter_next (GTK_TREE_MODEL (fixture->store),
868                                       &iter) == FALSE);
869   g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == FALSE);
870   g_assert (iter.stamp == 0);
871 }
872
873 static void
874 list_store_test_iter_children_invalid (ListStore     *fixture,
875                                        gconstpointer  user_data)
876 {
877   GtkTreeIter iter, child;
878
879   gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &iter);
880   g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == TRUE);
881
882   g_assert (gtk_tree_model_iter_children (GTK_TREE_MODEL (fixture->store),
883                                           &child, &iter) == FALSE);
884   g_assert (gtk_list_store_iter_is_valid (fixture->store, &child) == FALSE);
885   g_assert (child.stamp == 0);
886 }
887
888 static void
889 list_store_test_iter_nth_child_invalid (ListStore     *fixture,
890                                         gconstpointer  user_data)
891 {
892   GtkTreeIter iter, child;
893
894   gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &iter);
895   g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == TRUE);
896
897   g_assert (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (fixture->store),
898                                            &child, &iter, 0) == FALSE);
899   g_assert (gtk_list_store_iter_is_valid (fixture->store, &child) == FALSE);
900   g_assert (child.stamp == 0);
901 }
902
903 static void
904 list_store_test_iter_parent_invalid (ListStore     *fixture,
905                                      gconstpointer  user_data)
906 {
907   GtkTreeIter iter, child;
908
909   gtk_tree_model_get_iter_first (GTK_TREE_MODEL (fixture->store), &child);
910   g_assert (gtk_list_store_iter_is_valid (fixture->store, &child) == TRUE);
911
912   g_assert (gtk_tree_model_iter_parent (GTK_TREE_MODEL (fixture->store),
913                                         &iter, &child) == FALSE);
914   g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter) == FALSE);
915   g_assert (iter.stamp == 0);
916 }
917
918
919 /* main */
920
921 int
922 main (int    argc,
923       char **argv)
924 {
925   gtk_test_init (&argc, &argv, NULL);
926
927   /* insertion */
928   g_test_add_func ("/list-store/insert-high-values",
929                    list_store_test_insert_high_values);
930   g_test_add_func ("/list-store/append",
931                    list_store_test_append);
932   g_test_add_func ("/list-store/prepend",
933                    list_store_test_prepend);
934   g_test_add_func ("/list-store/insert-after",
935                    list_store_test_insert_after);
936   g_test_add_func ("/list-store/insert-after-NULL",
937                    list_store_test_insert_after_NULL);
938   g_test_add_func ("/list-store/insert-before",
939                    list_store_test_insert_before);
940   g_test_add_func ("/list-store/insert-before-NULL",
941                    list_store_test_insert_before_NULL);
942
943   /* setting values (FIXME) */
944
945   /* removal */
946   g_test_add ("/list-store/remove-begin", ListStore, NULL,
947               list_store_setup, list_store_test_remove_begin,
948               list_store_teardown);
949   g_test_add ("/list-store/remove-middle", ListStore, NULL,
950               list_store_setup, list_store_test_remove_middle,
951               list_store_teardown);
952   g_test_add ("/list-store/remove-end", ListStore, NULL,
953               list_store_setup, list_store_test_remove_end,
954               list_store_teardown);
955
956   g_test_add ("/list-store/clear", ListStore, NULL,
957               list_store_setup, list_store_test_clear,
958               list_store_teardown);
959
960   /* reordering */
961   g_test_add ("/list-store/reorder", ListStore, NULL,
962               list_store_setup, list_store_test_reorder,
963               list_store_teardown);
964
965   /* swapping */
966   g_test_add ("/list-store/swap-begin", ListStore, NULL,
967               list_store_setup, list_store_test_swap_begin,
968               list_store_teardown);
969   g_test_add ("/list-store/swap-middle-next", ListStore, NULL,
970               list_store_setup, list_store_test_swap_middle_next,
971               list_store_teardown);
972   g_test_add ("/list-store/swap-middle-apart", ListStore, NULL,
973               list_store_setup, list_store_test_swap_middle_apart,
974               list_store_teardown);
975   g_test_add ("/list-store/swap-end", ListStore, NULL,
976               list_store_setup, list_store_test_swap_end,
977               list_store_teardown);
978   g_test_add_func ("/list-store/swap-single",
979                    list_store_test_swap_single);
980
981   /* moving */
982   g_test_add ("/list-store/move-after-from-start", ListStore, NULL,
983               list_store_setup, list_store_test_move_after_from_start,
984               list_store_teardown);
985   g_test_add ("/list-store/move-after-next", ListStore, NULL,
986               list_store_setup, list_store_test_move_after_next,
987               list_store_teardown);
988   g_test_add ("/list-store/move-after-apart", ListStore, NULL,
989               list_store_setup, list_store_test_move_after_apart,
990               list_store_teardown);
991   g_test_add ("/list-store/move-after-end", ListStore, NULL,
992               list_store_setup, list_store_test_move_after_end,
993               list_store_teardown);
994   g_test_add ("/list-store/move-after-from-end", ListStore, NULL,
995               list_store_setup, list_store_test_move_after_from_end,
996               list_store_teardown);
997   g_test_add ("/list-store/move-after-change-ends", ListStore, NULL,
998               list_store_setup, list_store_test_move_after_change_ends,
999               list_store_teardown);
1000   g_test_add ("/list-store/move-after-NULL", ListStore, NULL,
1001               list_store_setup, list_store_test_move_after_NULL,
1002               list_store_teardown);
1003   g_test_add_func ("/list-store/move-after-single",
1004                    list_store_test_move_after_single);
1005
1006   g_test_add ("/list-store/move-before-next", ListStore, NULL,
1007               list_store_setup, list_store_test_move_before_next,
1008               list_store_teardown);
1009   g_test_add ("/list-store/move-before-apart", ListStore, NULL,
1010               list_store_setup, list_store_test_move_before_apart,
1011               list_store_teardown);
1012   g_test_add ("/list-store/move-before-to-start", ListStore, NULL,
1013               list_store_setup, list_store_test_move_before_to_start,
1014               list_store_teardown);
1015   g_test_add ("/list-store/move-before-from-end", ListStore, NULL,
1016               list_store_setup, list_store_test_move_before_from_end,
1017               list_store_teardown);
1018   g_test_add ("/list-store/move-before-change-ends", ListStore, NULL,
1019               list_store_setup, list_store_test_move_before_change_ends,
1020               list_store_teardown);
1021   g_test_add ("/list-store/move-before-NULL", ListStore, NULL,
1022               list_store_setup, list_store_test_move_before_NULL,
1023               list_store_teardown);
1024   g_test_add_func ("/list-store/move-before-single",
1025                    list_store_test_move_before_single);
1026
1027   /* iter invalidation */
1028   g_test_add ("/list-store/iter-next-invalid", ListStore, NULL,
1029               list_store_setup, list_store_test_iter_next_invalid,
1030               list_store_teardown);
1031   g_test_add ("/list-store/iter-children-invalid", ListStore, NULL,
1032               list_store_setup, list_store_test_iter_children_invalid,
1033               list_store_teardown);
1034   g_test_add ("/list-store/iter-nth-child-invalid", ListStore, NULL,
1035               list_store_setup, list_store_test_iter_nth_child_invalid,
1036               list_store_teardown);
1037   g_test_add ("/list-store/iter-parent-invalid", ListStore, NULL,
1038               list_store_setup, list_store_test_iter_parent_invalid,
1039               list_store_teardown);
1040
1041   return g_test_run ();
1042 }