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