]> Pileus Git - ~andy/gtk/blob - gtk/tests/liststore.c
start composing tests for the list and tree store.
[~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  *  - We probably want to do all move and swap tests on a 1-item list store
23  *    also.
24  *  - Test implementations of the interfaces: DnD, sortable, buildable
25  *    and the tree model interface itself?
26  *  - Need to check if the emitted signals are right.
27  *  - Needs analysis with the code coverage tool once it is there.
28  */
29
30 #include <glib/gtestutils.h>
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 GtkListStore */
44
45   return TRUE;
46 }
47
48 /*
49  * Fixture
50  */
51 typedef struct
52 {
53   GtkTreeIter iter[5];
54   GtkListStore *store;
55 } ListStore;
56
57 static void
58 list_store_setup (ListStore     *fixture,
59                   gconstpointer  test_data)
60 {
61   int i;
62
63   fixture->store = gtk_list_store_new (1, G_TYPE_INT);
64
65   for (i = 0; i < 5; i++)
66     {
67       gtk_list_store_insert (fixture->store, &fixture->iter[i], i);
68       gtk_list_store_set (fixture->store, &fixture->iter[i], 0, i, -1);
69     }
70 }
71
72 static void
73 list_store_teardown (ListStore     *fixture,
74                      gconstpointer  test_data)
75 {
76   g_object_unref (fixture->store);
77 }
78
79 /*
80  * The actual tests.
81  */
82
83 static void
84 check_model (ListStore *fixture,
85              gint      *new_order,
86              gint       skip)
87 {
88   int i;
89   GtkTreePath *path;
90
91   path = gtk_tree_path_new ();
92   gtk_tree_path_down (path);
93
94   /* Check validity of the model and validity of the iters-persistent
95    * claim.
96    */
97   for (i = 0; i < 5; i++)
98     {
99       GtkTreeIter iter;
100
101       if (i == skip)
102         continue;
103
104       /* The saved iterator at new_order[i] should match the iterator
105        * at i.
106        */
107
108       gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store),
109                                &iter, path);
110
111       g_assert (gtk_list_store_iter_is_valid (fixture->store, &iter));
112       g_assert (iters_equal (&iter, &fixture->iter[new_order[i]]));
113
114       gtk_tree_path_next (path);
115     }
116
117   gtk_tree_path_free (path);
118 }
119
120 /* removal */
121 static void
122 list_store_test_remove_begin (ListStore     *fixture,
123                               gconstpointer  user_data)
124 {
125   int new_order[5] = { -1, 1, 2, 3, 4 };
126   GtkTreePath *path;
127   GtkTreeIter iter;
128
129   /* Remove node at 0 */
130   path = gtk_tree_path_new_from_indices (0, -1);
131   gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
132   gtk_tree_path_free (path);
133
134   g_assert (gtk_list_store_remove (fixture->store, &iter) == TRUE);
135   g_assert (!gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[0]));
136   g_assert (iters_equal (&iter, &fixture->iter[1]));
137
138   check_model (fixture, new_order, 0);
139 }
140
141 static void
142 list_store_test_remove_middle (ListStore     *fixture,
143                                gconstpointer  user_data)
144 {
145   int new_order[5] = { 0, 1, -1, 3, 4 };
146   GtkTreePath *path;
147   GtkTreeIter iter;
148
149   /* Remove node at 2 */
150   path = gtk_tree_path_new_from_indices (2, -1);
151   gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
152   gtk_tree_path_free (path);
153
154   g_assert (gtk_list_store_remove (fixture->store, &iter) == TRUE);
155   g_assert (!gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[2]));
156   g_assert (iters_equal (&iter, &fixture->iter[3]));
157
158   check_model (fixture, new_order, 2);
159 }
160
161 static void
162 list_store_test_remove_end (ListStore     *fixture,
163                             gconstpointer  user_data)
164 {
165   int new_order[5] = { 0, 1, 2, 3, -1 };
166   GtkTreePath *path;
167   GtkTreeIter iter;
168
169   /* Remove node at 4 */
170   path = gtk_tree_path_new_from_indices (4, -1);
171   gtk_tree_model_get_iter (GTK_TREE_MODEL (fixture->store), &iter, path);
172   gtk_tree_path_free (path);
173
174   g_assert (gtk_list_store_remove (fixture->store, &iter) == FALSE);
175   g_assert (!gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[4]));
176
177   check_model (fixture, new_order, 4);
178 }
179
180 static void
181 list_store_test_clear (ListStore     *fixture,
182                        gconstpointer  user_data)
183 {
184   int i;
185
186   gtk_list_store_clear (fixture->store);
187
188   g_assert (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (fixture->store), NULL) == 0);
189
190   for (i = 0; i < 5; i++)
191     g_assert (!gtk_list_store_iter_is_valid (fixture->store, &fixture->iter[i]));
192 }
193
194 /* reorder */
195
196 static void
197 list_store_test_reorder (ListStore     *fixture,
198                          gconstpointer  user_data)
199 {
200   int new_order[5] = { 4, 1, 0, 2, 3 };
201
202   gtk_list_store_reorder (fixture->store, new_order);
203   check_model (fixture, new_order, -1);
204 }
205
206 /* swapping */
207
208 static void
209 list_store_test_swap_begin (ListStore     *fixture,
210                             gconstpointer  user_data)
211 {
212   /* We swap nodes 0 and 1 at the beginning */
213   int new_order[5] = { 1, 0, 2, 3, 4 };
214
215   GtkTreeIter iter_a;
216   GtkTreeIter iter_b;
217
218   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "0"));
219   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "1"));
220
221   gtk_list_store_swap (fixture->store, &iter_a, &iter_b);
222   check_model (fixture, new_order, -1);
223 }
224
225 static void
226 list_store_test_swap_middle_next (ListStore     *fixture,
227                                   gconstpointer  user_data)
228 {
229   /* We swap nodes 2 and 3 in the middle that are next to each other */
230   int new_order[5] = { 0, 1, 3, 2, 4 };
231
232   GtkTreeIter iter_a;
233   GtkTreeIter iter_b;
234
235   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "2"));
236   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "3"));
237
238   gtk_list_store_swap (fixture->store, &iter_a, &iter_b);
239   check_model (fixture, new_order, -1);
240 }
241
242 static void
243 list_store_test_swap_middle_apart (ListStore     *fixture,
244                                    gconstpointer  user_data)
245 {
246   /* We swap nodes 1 and 3 in the middle that are apart from each other */
247   int new_order[5] = { 0, 3, 2, 1, 4 };
248
249   GtkTreeIter iter_a;
250   GtkTreeIter iter_b;
251
252   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "1"));
253   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "3"));
254
255   gtk_list_store_swap (fixture->store, &iter_a, &iter_b);
256   check_model (fixture, new_order, -1);
257 }
258
259 static void
260 list_store_test_swap_end (ListStore     *fixture,
261                           gconstpointer  user_data)
262 {
263   /* We swap nodes 3 and 4 at the end */
264   int new_order[5] = { 0, 1, 2, 4, 3 };
265
266   GtkTreeIter iter_a;
267   GtkTreeIter iter_b;
268
269   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_a, "3"));
270   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter_b, "4"));
271
272   gtk_list_store_swap (fixture->store, &iter_a, &iter_b);
273   check_model (fixture, new_order, -1);
274 }
275
276 /* move after */
277
278 static void
279 list_store_test_move_after_from_start (ListStore     *fixture,
280                                        gconstpointer  user_data)
281 {
282   /* We move node 0 after 2 */
283   int new_order[5] = { 1, 2, 0, 3, 4 };
284
285   GtkTreeIter iter;
286   GtkTreeIter position;
287
288   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "0"));
289   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "2"));
290
291   gtk_list_store_move_after (fixture->store, &iter, &position);
292   check_model (fixture, new_order, -1);
293 }
294
295 static void
296 list_store_test_move_after_next (ListStore     *fixture,
297                                  gconstpointer  user_data)
298 {
299   /* We move node 2 after 3 */
300   int new_order[5] = { 0, 1, 3, 2, 4 };
301
302   GtkTreeIter iter;
303   GtkTreeIter position;
304
305   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
306   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "3"));
307
308   gtk_list_store_move_after (fixture->store, &iter, &position);
309   check_model (fixture, new_order, -1);
310 }
311
312 static void
313 list_store_test_move_after_apart (ListStore     *fixture,
314                                   gconstpointer  user_data)
315 {
316   /* We move node 1 after 3 */
317   int new_order[5] = { 0, 2, 3, 1, 4 };
318
319   GtkTreeIter iter;
320   GtkTreeIter position;
321
322   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "1"));
323   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "3"));
324
325   gtk_list_store_move_after (fixture->store, &iter, &position);
326   check_model (fixture, new_order, -1);
327 }
328
329 static void
330 list_store_test_move_after_end (ListStore     *fixture,
331                                 gconstpointer  user_data)
332 {
333   /* We move node 2 after 4 */
334   int new_order[5] = { 0, 1, 3, 4, 2 };
335
336   GtkTreeIter iter;
337   GtkTreeIter position;
338
339   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
340   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "4"));
341
342   gtk_list_store_move_after (fixture->store, &iter, &position);
343   check_model (fixture, new_order, -1);
344 }
345
346 static void
347 list_store_test_move_after_from_end (ListStore     *fixture,
348                                      gconstpointer  user_data)
349 {
350   /* We move node 4 after 1 */
351   int new_order[5] = { 0, 1, 4, 2, 3 };
352
353   GtkTreeIter iter;
354   GtkTreeIter position;
355
356   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "4"));
357   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "1"));
358
359   gtk_list_store_move_after (fixture->store, &iter, &position);
360   check_model (fixture, new_order, -1);
361 }
362
363 static void
364 list_store_test_move_after_change_ends (ListStore     *fixture,
365                                         gconstpointer  user_data)
366 {
367   /* We move 0 after 4, this will cause both the head and tail ends to
368    * change.
369    */
370   int new_order[5] = { 1, 2, 3, 4, 0 };
371
372   GtkTreeIter iter;
373   GtkTreeIter position;
374
375   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "0"));
376   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "4"));
377
378   gtk_list_store_move_after (fixture->store, &iter, &position);
379   check_model (fixture, new_order, -1);
380 }
381
382 static void
383 list_store_test_move_after_NULL (ListStore     *fixture,
384                                  gconstpointer  user_data)
385 {
386   /* We move node 2, NULL should prepend */
387   int new_order[5] = { 2, 0, 1, 3, 4 };
388
389   GtkTreeIter iter;
390
391   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
392
393   gtk_list_store_move_after (fixture->store, &iter, NULL);
394   check_model (fixture, new_order, -1);
395 }
396
397 /* move before */
398
399 static void
400 list_store_test_move_before_next (ListStore     *fixture,
401                                   gconstpointer  user_data)
402 {
403   /* We move node 3 before 2 */
404   int new_order[5] = { 0, 1, 3, 2, 4 };
405
406   GtkTreeIter iter;
407   GtkTreeIter position;
408
409   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "3"));
410   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "2"));
411
412   gtk_list_store_move_before (fixture->store, &iter, &position);
413   check_model (fixture, new_order, -1);
414 }
415
416 static void
417 list_store_test_move_before_apart (ListStore     *fixture,
418                                    gconstpointer  user_data)
419 {
420   /* We move node 1 before 3 */
421   int new_order[5] = { 0, 2, 1, 3, 4 };
422
423   GtkTreeIter iter;
424   GtkTreeIter position;
425
426   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "1"));
427   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "3"));
428
429   gtk_list_store_move_before (fixture->store, &iter, &position);
430   check_model (fixture, new_order, -1);
431 }
432
433 static void
434 list_store_test_move_before_to_start (ListStore     *fixture,
435                                       gconstpointer  user_data)
436 {
437   /* We move node 2 before 0 */
438   int new_order[5] = { 2, 0, 1, 3, 4 };
439
440   GtkTreeIter iter;
441   GtkTreeIter position;
442
443   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
444   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "0"));
445
446   gtk_list_store_move_before (fixture->store, &iter, &position);
447   check_model (fixture, new_order, -1);
448 }
449
450 static void
451 list_store_test_move_before_from_end (ListStore     *fixture,
452                                       gconstpointer  user_data)
453 {
454   /* We move node 4 before 2 (replace end) */
455   int new_order[5] = { 0, 1, 4, 2, 3 };
456
457   GtkTreeIter iter;
458   GtkTreeIter position;
459
460   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "4"));
461   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "2"));
462
463   gtk_list_store_move_before (fixture->store, &iter, &position);
464   check_model (fixture, new_order, -1);
465 }
466
467 static void
468 list_store_test_move_before_change_ends (ListStore     *fixture,
469                                          gconstpointer  user_data)
470 {
471   /* We move node 4 before 0 */
472   int new_order[5] = { 4, 0, 1, 2, 3 };
473
474   GtkTreeIter iter;
475   GtkTreeIter position;
476
477   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "4"));
478   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &position, "0"));
479
480   gtk_list_store_move_before (fixture->store, &iter, &position);
481   check_model (fixture, new_order, -1);
482 }
483
484 static void
485 list_store_test_move_before_NULL (ListStore     *fixture,
486                                   gconstpointer  user_data)
487 {
488   /* We move node 2, NULL should append */
489   int new_order[5] = { 0, 1, 3, 4, 2 };
490
491   GtkTreeIter iter;
492
493   g_assert (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (fixture->store), &iter, "2"));
494
495   gtk_list_store_move_before (fixture->store, &iter, NULL);
496   check_model (fixture, new_order, -1);
497 }
498
499 /* main */
500
501 int
502 main (int    argc,
503       char **argv)
504 {
505   gtk_test_init (&argc, &argv, NULL);
506
507   /* insertion (FIXME) */
508
509   /* setting values (FIXME) */
510
511   /* removal */
512   g_test_add ("/list-store/remove-begin", ListStore, NULL,
513               list_store_setup, list_store_test_remove_begin,
514               list_store_teardown);
515   g_test_add ("/list-store/remove-middle", ListStore, NULL,
516               list_store_setup, list_store_test_remove_middle,
517               list_store_teardown);
518   g_test_add ("/list-store/remove-end", ListStore, NULL,
519               list_store_setup, list_store_test_remove_end,
520               list_store_teardown);
521
522   g_test_add ("/list-store/clear", ListStore, NULL,
523               list_store_setup, list_store_test_clear,
524               list_store_teardown);
525
526   /* reordering */
527   g_test_add ("/list-store/reorder", ListStore, NULL,
528               list_store_setup, list_store_test_reorder,
529               list_store_teardown);
530
531   /* swapping */
532   g_test_add ("/list-store/swap-begin", ListStore, NULL,
533               list_store_setup, list_store_test_swap_begin,
534               list_store_teardown);
535   g_test_add ("/list-store/swap-middle-next", ListStore, NULL,
536               list_store_setup, list_store_test_swap_middle_next,
537               list_store_teardown);
538   g_test_add ("/list-store/swap-middle-apart", ListStore, NULL,
539               list_store_setup, list_store_test_swap_middle_apart,
540               list_store_teardown);
541   g_test_add ("/list-store/swap-end", ListStore, NULL,
542               list_store_setup, list_store_test_swap_end,
543               list_store_teardown);
544
545   /* moving */
546   g_test_add ("/list-store/move-after-from-start", ListStore, NULL,
547               list_store_setup, list_store_test_move_after_from_start,
548               list_store_teardown);
549   g_test_add ("/list-store/move-after-next", ListStore, NULL,
550               list_store_setup, list_store_test_move_after_next,
551               list_store_teardown);
552   g_test_add ("/list-store/move-after-apart", ListStore, NULL,
553               list_store_setup, list_store_test_move_after_apart,
554               list_store_teardown);
555   g_test_add ("/list-store/move-after-end", ListStore, NULL,
556               list_store_setup, list_store_test_move_after_end,
557               list_store_teardown);
558   g_test_add ("/list-store/move-after-from-end", ListStore, NULL,
559               list_store_setup, list_store_test_move_after_from_end,
560               list_store_teardown);
561   g_test_add ("/list-store/move-after-change-ends", ListStore, NULL,
562               list_store_setup, list_store_test_move_after_change_ends,
563               list_store_teardown);
564   g_test_add ("/list-store/move-after-NULL", ListStore, NULL,
565               list_store_setup, list_store_test_move_after_NULL,
566               list_store_teardown);
567
568   g_test_add ("/list-store/move-before-next", ListStore, NULL,
569               list_store_setup, list_store_test_move_before_next,
570               list_store_teardown);
571   g_test_add ("/list-store/move-before-apart", ListStore, NULL,
572               list_store_setup, list_store_test_move_before_apart,
573               list_store_teardown);
574   g_test_add ("/list-store/move-before-to-start", ListStore, NULL,
575               list_store_setup, list_store_test_move_before_to_start,
576               list_store_teardown);
577   g_test_add ("/list-store/move-before-from-end", ListStore, NULL,
578               list_store_setup, list_store_test_move_before_from_end,
579               list_store_teardown);
580   g_test_add ("/list-store/move-before-change-ends", ListStore, NULL,
581               list_store_setup, list_store_test_move_before_change_ends,
582               list_store_teardown);
583   g_test_add ("/list-store/move-before-NULL", ListStore, NULL,
584               list_store_setup, list_store_test_move_before_NULL,
585               list_store_teardown);
586
587   return g_test_run ();
588 }