]> Pileus Git - ~andy/gtk/blob - gtk/tests/modelrefcount.c
c701287927100f62612f8a6561b07d403996bc84
[~andy/gtk] / gtk / tests / modelrefcount.c
1 /* GtkTreeModel ref counting tests
2  * Copyright (C) 2011  Kristian Rietveld  <kris@gtk.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #include "gtktreemodelrefcount.h"
21 #include "treemodel.h"
22
23 /* And the tests themselves */
24
25 static void
26 test_list_no_reference (void)
27 {
28   GtkTreeIter iter;
29   GtkTreeModel *model;
30   GtkTreeModelRefCount *ref_model;
31
32   model = gtk_tree_model_ref_count_new ();
33   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
34
35   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
36   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
37   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
38   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
39   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
40
41   assert_root_level_unreferenced (ref_model);
42
43   g_object_unref (ref_model);
44 }
45
46 static void
47 test_list_reference_during_creation (void)
48 {
49   GtkTreeIter iter;
50   GtkTreeModel *model;
51   GtkTreeModelRefCount *ref_model;
52   GtkWidget *tree_view;
53
54   model = gtk_tree_model_ref_count_new ();
55   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
56   tree_view = gtk_tree_view_new_with_model (model);
57
58   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
59   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
60   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
61   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
62   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
63
64   assert_root_level_referenced (ref_model, 1);
65
66   gtk_widget_destroy (tree_view);
67
68   assert_root_level_unreferenced (ref_model);
69
70   g_object_unref (ref_model);
71 }
72
73 static void
74 test_list_reference_after_creation (void)
75 {
76   GtkTreeIter iter;
77   GtkTreeModel *model;
78   GtkTreeModelRefCount *ref_model;
79   GtkWidget *tree_view;
80
81   model = gtk_tree_model_ref_count_new ();
82   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
83
84   assert_root_level_unreferenced (ref_model);
85
86   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
87   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
88   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
89   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
90   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
91
92   tree_view = gtk_tree_view_new_with_model (model);
93
94   assert_root_level_referenced (ref_model, 1);
95
96   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
97   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
98
99   assert_root_level_referenced (ref_model, 1);
100
101   gtk_widget_destroy (tree_view);
102
103   assert_root_level_unreferenced (ref_model);
104
105   g_object_unref (ref_model);
106 }
107
108 static void
109 test_list_reference_reordered (void)
110 {
111   GtkTreeIter iter1, iter2, iter3, iter4, iter5;
112   GtkTreeModel *model;
113   GtkTreeModelRefCount *ref_model;
114   GtkWidget *tree_view;
115
116   model = gtk_tree_model_ref_count_new ();
117   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
118
119   assert_root_level_unreferenced (ref_model);
120
121   gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
122   gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
123   gtk_tree_store_append (GTK_TREE_STORE (model), &iter3, NULL);
124   gtk_tree_store_append (GTK_TREE_STORE (model), &iter4, NULL);
125   gtk_tree_store_append (GTK_TREE_STORE (model), &iter5, NULL);
126
127   tree_view = gtk_tree_view_new_with_model (model);
128
129   assert_root_level_referenced (ref_model, 1);
130
131   gtk_tree_store_move_after (GTK_TREE_STORE (model),
132                              &iter1, &iter5);
133
134   assert_root_level_referenced (ref_model, 1);
135
136   gtk_tree_store_move_after (GTK_TREE_STORE (model),
137                              &iter3, &iter4);
138
139   assert_root_level_referenced (ref_model, 1);
140
141   gtk_widget_destroy (tree_view);
142
143   assert_root_level_unreferenced (ref_model);
144
145   g_object_unref (ref_model);
146 }
147
148
149 static void
150 test_tree_no_reference (void)
151 {
152   GtkTreeIter iter, child;
153   GtkTreeModel *model;
154   GtkTreeModelRefCount *ref_model;
155
156   model = gtk_tree_model_ref_count_new ();
157   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
158
159   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
160   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
161   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
162   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
163   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
164   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
165   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
166   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
167   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
168   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
169   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
170
171   assert_entire_model_unreferenced (ref_model);
172
173   g_object_unref (ref_model);
174 }
175
176 static void
177 test_tree_reference_during_creation (void)
178 {
179   GtkTreeIter iter, child;
180   GtkTreeModel *model;
181   GtkTreeModelRefCount *ref_model;
182   GtkWidget *tree_view;
183
184   model = gtk_tree_model_ref_count_new ();
185   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
186   tree_view = gtk_tree_view_new_with_model (model);
187
188   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
189   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
190   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
191   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
192   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
193   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
194   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
195   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
196   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
197   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
198   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
199
200   assert_root_level_referenced (ref_model, 1);
201   assert_not_entire_model_referenced (ref_model, 1);
202   assert_level_unreferenced (ref_model, &child);
203
204   gtk_widget_destroy (tree_view);
205
206   assert_entire_model_unreferenced (ref_model);
207
208   g_object_unref (ref_model);
209 }
210
211 static void
212 test_tree_reference_after_creation (void)
213 {
214   GtkTreeIter iter, child;
215   GtkTreeModel *model;
216   GtkTreeModelRefCount *ref_model;
217   GtkWidget *tree_view;
218
219   model = gtk_tree_model_ref_count_new ();
220   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
221
222   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
223   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
224   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
225   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
226   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
227   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
228   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
229   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
230   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
231   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
232   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
233
234   assert_entire_model_unreferenced (ref_model);
235
236   tree_view = gtk_tree_view_new_with_model (model);
237
238   assert_root_level_referenced (ref_model, 1);
239   assert_not_entire_model_referenced (ref_model, 1);
240   assert_level_unreferenced (ref_model, &child);
241
242   gtk_widget_destroy (tree_view);
243
244   assert_entire_model_unreferenced (ref_model);
245
246   g_object_unref (ref_model);
247 }
248
249 static void
250 test_tree_reference_reordered (void)
251 {
252   GtkTreeIter parent;
253   GtkTreeIter iter1, iter2, iter3, iter4, iter5;
254   GtkTreeModel *model;
255   GtkTreeModelRefCount *ref_model;
256   GtkWidget *tree_view;
257
258   model = gtk_tree_model_ref_count_new ();
259   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
260
261   assert_root_level_unreferenced (ref_model);
262
263   gtk_tree_store_append (GTK_TREE_STORE (model), &parent, NULL);
264   gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, &parent);
265   gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, &parent);
266   gtk_tree_store_append (GTK_TREE_STORE (model), &iter3, &parent);
267   gtk_tree_store_append (GTK_TREE_STORE (model), &iter4, &parent);
268   gtk_tree_store_append (GTK_TREE_STORE (model), &iter5, &parent);
269
270   tree_view = gtk_tree_view_new_with_model (model);
271   gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
272
273   assert_entire_model_referenced (ref_model, 1);
274
275   gtk_tree_store_move_after (GTK_TREE_STORE (model),
276                              &iter1, &iter5);
277
278   assert_entire_model_referenced (ref_model, 1);
279
280   gtk_tree_store_move_after (GTK_TREE_STORE (model),
281                              &iter3, &iter4);
282
283   assert_entire_model_referenced (ref_model, 1);
284
285   gtk_widget_destroy (tree_view);
286
287   assert_entire_model_unreferenced (ref_model);
288
289   g_object_unref (ref_model);
290 }
291
292 static void
293 test_tree_reference_expand_all (void)
294 {
295   GtkTreeIter iter, child;
296   GtkTreeModel *model;
297   GtkTreeModelRefCount *ref_model;
298   GtkWidget *tree_view;
299
300   model = gtk_tree_model_ref_count_new ();
301   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
302
303   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
304   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
305   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
306   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
307   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
308   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
309   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
310   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
311   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
312   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
313   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
314
315   assert_entire_model_unreferenced (ref_model);
316
317   tree_view = gtk_tree_view_new_with_model (model);
318
319   assert_root_level_referenced (ref_model, 1);
320   assert_not_entire_model_referenced (ref_model, 1);
321   assert_level_unreferenced (ref_model, &child);
322
323   gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
324
325   assert_entire_model_referenced (ref_model, 1);
326
327   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
328   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
329   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
330
331   assert_root_level_referenced (ref_model, 1);
332   assert_not_entire_model_referenced (ref_model, 1);
333   assert_level_unreferenced (ref_model, &child);
334
335   gtk_widget_destroy (tree_view);
336
337   assert_entire_model_unreferenced (ref_model);
338
339   g_object_unref (ref_model);
340 }
341
342 static void
343 test_tree_reference_collapse_all (void)
344 {
345   GtkTreeIter iter, child;
346   GtkTreeModel *model;
347   GtkTreeModelRefCount *ref_model;
348   GtkWidget *tree_view;
349
350   model = gtk_tree_model_ref_count_new ();
351   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
352
353   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
354   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
355   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
356   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
357   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
358   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
359   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
360   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
361   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
362   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
363   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
364
365   assert_entire_model_unreferenced (ref_model);
366
367   tree_view = gtk_tree_view_new_with_model (model);
368   gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
369
370   assert_entire_model_referenced (ref_model, 1);
371
372   gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
373
374   assert_root_level_referenced (ref_model, 1);
375   assert_not_entire_model_referenced (ref_model, 1);
376   assert_level_unreferenced (ref_model, &child);
377
378   gtk_widget_destroy (tree_view);
379
380   assert_entire_model_unreferenced (ref_model);
381
382   g_object_unref (ref_model);
383 }
384
385 static void
386 test_tree_reference_expand_collapse (void)
387 {
388   GtkTreeIter parent1, parent2, child;
389   GtkTreePath *path1, *path2;
390   GtkTreeModel *model;
391   GtkTreeModelRefCount *ref_model;
392   GtkWidget *tree_view;
393
394   model = gtk_tree_model_ref_count_new ();
395   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
396   tree_view = gtk_tree_view_new_with_model (model);
397
398   gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, NULL);
399   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &parent1);
400   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &parent1);
401   gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, NULL);
402   gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, NULL);
403   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &parent2);
404   gtk_tree_store_append (GTK_TREE_STORE (model), &child, &parent2);
405
406   path1 = gtk_tree_model_get_path (model, &parent1);
407   path2 = gtk_tree_model_get_path (model, &parent2);
408
409   assert_level_unreferenced (ref_model, &parent1);
410   assert_level_unreferenced (ref_model, &parent2);
411
412   gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path1, FALSE);
413
414   assert_level_referenced (ref_model, 1, &parent1);
415   assert_level_unreferenced (ref_model, &parent2);
416
417   gtk_tree_view_collapse_row (GTK_TREE_VIEW (tree_view), path1);
418
419   assert_level_unreferenced (ref_model, &parent1);
420   assert_level_unreferenced (ref_model, &parent2);
421
422   gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path2, FALSE);
423
424   assert_level_unreferenced (ref_model, &parent1);
425   assert_level_referenced (ref_model, 1, &parent2);
426
427   gtk_tree_view_collapse_row (GTK_TREE_VIEW (tree_view), path2);
428
429   assert_level_unreferenced (ref_model, &parent1);
430   assert_level_unreferenced (ref_model, &parent2);
431
432   gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path2, FALSE);
433
434   assert_level_unreferenced (ref_model, &parent1);
435   assert_level_referenced (ref_model, 1, &parent2);
436
437   gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path1, FALSE);
438
439   assert_level_referenced (ref_model, 1, &parent1);
440   assert_level_referenced (ref_model, 1, &parent2);
441
442   gtk_tree_path_free (path1);
443   gtk_tree_path_free (path2);
444
445   gtk_widget_destroy (tree_view);
446   g_object_unref (ref_model);
447 }
448
449 static void
450 test_row_reference_list (void)
451 {
452   GtkTreeIter iter0, iter1, iter2;
453   GtkTreePath *path;
454   GtkTreeModel *model;
455   GtkTreeModelRefCount *ref_model;
456   GtkTreeRowReference *row_ref;
457   GtkWidget *tree_view;
458
459   model = gtk_tree_model_ref_count_new ();
460   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
461
462   gtk_tree_store_append (GTK_TREE_STORE (model), &iter0, NULL);
463   gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
464   gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
465
466   assert_root_level_unreferenced (ref_model);
467
468   /* create and remove a row ref and check reference counts */
469   path = gtk_tree_path_new_from_indices (1, -1);
470   row_ref = gtk_tree_row_reference_new (model, path);
471
472   assert_node_ref_count (ref_model, &iter0, 0);
473   assert_node_ref_count (ref_model, &iter1, 1);
474   assert_node_ref_count (ref_model, &iter2, 0);
475
476   gtk_tree_row_reference_free (row_ref);
477
478   assert_root_level_unreferenced (ref_model);
479
480   /* the same, but then also with a tree view monitoring the model */
481   tree_view = gtk_tree_view_new_with_model (model);
482
483   assert_root_level_referenced (ref_model, 1);
484
485   row_ref = gtk_tree_row_reference_new (model, path);
486
487   assert_node_ref_count (ref_model, &iter0, 1);
488   assert_node_ref_count (ref_model, &iter1, 2);
489   assert_node_ref_count (ref_model, &iter2, 1);
490
491   gtk_widget_destroy (tree_view);
492
493   assert_node_ref_count (ref_model, &iter0, 0);
494   assert_node_ref_count (ref_model, &iter1, 1);
495   assert_node_ref_count (ref_model, &iter2, 0);
496
497   gtk_tree_row_reference_free (row_ref);
498
499   assert_root_level_unreferenced (ref_model);
500
501   gtk_tree_path_free (path);
502
503   g_object_unref (ref_model);
504 }
505
506 static void
507 test_row_reference_list_remove (void)
508 {
509   GtkTreeIter iter0, iter1, iter2;
510   GtkTreePath *path;
511   GtkTreeModel *model;
512   GtkTreeModelRefCount *ref_model;
513   GtkTreeRowReference *row_ref;
514
515   model = gtk_tree_model_ref_count_new ();
516   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
517
518   gtk_tree_store_append (GTK_TREE_STORE (model), &iter0, NULL);
519   gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
520   gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
521
522   assert_root_level_unreferenced (ref_model);
523
524   /* test creating the row reference and then removing the node */
525   path = gtk_tree_path_new_from_indices (1, -1);
526   row_ref = gtk_tree_row_reference_new (model, path);
527
528   assert_node_ref_count (ref_model, &iter0, 0);
529   assert_node_ref_count (ref_model, &iter1, 1);
530   assert_node_ref_count (ref_model, &iter2, 0);
531
532   gtk_tree_store_remove (GTK_TREE_STORE (model), &iter1);
533
534   assert_root_level_unreferenced (ref_model);
535
536   gtk_tree_row_reference_free (row_ref);
537
538   assert_root_level_unreferenced (ref_model);
539
540   /* test creating a row ref, removing another node and then removing
541    * the row ref node.
542    */
543   row_ref = gtk_tree_row_reference_new (model, path);
544
545   assert_node_ref_count (ref_model, &iter0, 0);
546   assert_node_ref_count (ref_model, &iter2, 1);
547
548   gtk_tree_store_remove (GTK_TREE_STORE (model), &iter0);
549
550   assert_root_level_referenced (ref_model, 1);
551
552   gtk_tree_store_remove (GTK_TREE_STORE (model), &iter2);
553
554   g_assert (!gtk_tree_model_get_iter_first (model, &iter0));
555
556   gtk_tree_row_reference_free (row_ref);
557
558   gtk_tree_path_free (path);
559
560   g_object_unref (ref_model);
561 }
562
563 static void
564 test_row_reference_tree (void)
565 {
566   GtkTreeIter iter0, iter1, iter2;
567   GtkTreeIter child0, child1, child2;
568   GtkTreeIter grandchild0, grandchild1, grandchild2;
569   GtkTreePath *path;
570   GtkTreeModel *model;
571   GtkTreeModelRefCount *ref_model;
572   GtkTreeRowReference *row_ref, *row_ref1;
573   GtkWidget *tree_view;
574
575   model = gtk_tree_model_ref_count_new ();
576   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
577
578   gtk_tree_store_append (GTK_TREE_STORE (model), &iter0, NULL);
579   gtk_tree_store_append (GTK_TREE_STORE (model), &child0, &iter0);
580   gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild0, &child0);
581   gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
582   gtk_tree_store_append (GTK_TREE_STORE (model), &child1, &iter1);
583   gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild1, &child1);
584   gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
585   gtk_tree_store_append (GTK_TREE_STORE (model), &child2, &iter2);
586   gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild2, &child2);
587
588   assert_entire_model_unreferenced (ref_model);
589
590   /* create and remove a row ref and check reference counts */
591   path = gtk_tree_path_new_from_indices (1, 0, 0, -1);
592   row_ref = gtk_tree_row_reference_new (model, path);
593   gtk_tree_path_free (path);
594
595   assert_node_ref_count (ref_model, &iter0, 0);
596   assert_node_ref_count (ref_model, &child0, 0);
597   assert_node_ref_count (ref_model, &grandchild0, 0);
598   assert_node_ref_count (ref_model, &iter1, 1);
599   assert_node_ref_count (ref_model, &child1, 1);
600   assert_node_ref_count (ref_model, &grandchild1, 1);
601   assert_node_ref_count (ref_model, &iter2, 0);
602   assert_node_ref_count (ref_model, &child2, 0);
603   assert_node_ref_count (ref_model, &grandchild2, 0);
604
605   gtk_tree_row_reference_free (row_ref);
606
607   assert_entire_model_unreferenced (ref_model);
608
609   /* again, with path 1:1 */
610   path = gtk_tree_path_new_from_indices (1, 0, -1);
611   row_ref = gtk_tree_row_reference_new (model, path);
612   gtk_tree_path_free (path);
613
614   assert_node_ref_count (ref_model, &iter0, 0);
615   assert_node_ref_count (ref_model, &child0, 0);
616   assert_node_ref_count (ref_model, &grandchild0, 0);
617   assert_node_ref_count (ref_model, &iter1, 1);
618   assert_node_ref_count (ref_model, &child1, 1);
619   assert_node_ref_count (ref_model, &grandchild1, 0);
620   assert_node_ref_count (ref_model, &iter2, 0);
621   assert_node_ref_count (ref_model, &child2, 0);
622   assert_node_ref_count (ref_model, &grandchild2, 0);
623
624   gtk_tree_row_reference_free (row_ref);
625
626   assert_entire_model_unreferenced (ref_model);
627
628   /* both row refs existent at once and also with a tree view monitoring
629    * the model
630    */
631   tree_view = gtk_tree_view_new_with_model (model);
632
633   assert_root_level_referenced (ref_model, 1);
634
635   path = gtk_tree_path_new_from_indices (1, 0, 0, -1);
636   row_ref = gtk_tree_row_reference_new (model, path);
637   gtk_tree_path_free (path);
638
639   assert_node_ref_count (ref_model, &iter0, 1);
640   assert_node_ref_count (ref_model, &child0, 0);
641   assert_node_ref_count (ref_model, &grandchild0, 0);
642   assert_node_ref_count (ref_model, &iter1, 2);
643   assert_node_ref_count (ref_model, &child1, 1);
644   assert_node_ref_count (ref_model, &grandchild1, 1);
645   assert_node_ref_count (ref_model, &iter2, 1);
646   assert_node_ref_count (ref_model, &child2, 0);
647   assert_node_ref_count (ref_model, &grandchild2, 0);
648
649   path = gtk_tree_path_new_from_indices (1, 0, -1);
650   row_ref1 = gtk_tree_row_reference_new (model, path);
651   gtk_tree_path_free (path);
652
653   assert_node_ref_count (ref_model, &iter0, 1);
654   assert_node_ref_count (ref_model, &child0, 0);
655   assert_node_ref_count (ref_model, &grandchild0, 0);
656   assert_node_ref_count (ref_model, &iter1, 3);
657   assert_node_ref_count (ref_model, &child1, 2);
658   assert_node_ref_count (ref_model, &grandchild1, 1);
659   assert_node_ref_count (ref_model, &iter2, 1);
660   assert_node_ref_count (ref_model, &child2, 0);
661   assert_node_ref_count (ref_model, &grandchild2, 0);
662
663   gtk_tree_row_reference_free (row_ref);
664
665   assert_node_ref_count (ref_model, &iter0, 1);
666   assert_node_ref_count (ref_model, &child0, 0);
667   assert_node_ref_count (ref_model, &grandchild0, 0);
668   assert_node_ref_count (ref_model, &iter1, 2);
669   assert_node_ref_count (ref_model, &child1, 1);
670   assert_node_ref_count (ref_model, &grandchild1, 0);
671   assert_node_ref_count (ref_model, &iter2, 1);
672   assert_node_ref_count (ref_model, &child2, 0);
673   assert_node_ref_count (ref_model, &grandchild2, 0);
674
675   gtk_widget_destroy (tree_view);
676
677   assert_node_ref_count (ref_model, &iter0, 0);
678   assert_node_ref_count (ref_model, &child0, 0);
679   assert_node_ref_count (ref_model, &grandchild0, 0);
680   assert_node_ref_count (ref_model, &iter1, 1);
681   assert_node_ref_count (ref_model, &child1, 1);
682   assert_node_ref_count (ref_model, &grandchild1, 0);
683   assert_node_ref_count (ref_model, &iter2, 0);
684   assert_node_ref_count (ref_model, &child2, 0);
685   assert_node_ref_count (ref_model, &grandchild2, 0);
686
687   gtk_tree_row_reference_free (row_ref1);
688
689   assert_root_level_unreferenced (ref_model);
690
691   g_object_unref (ref_model);
692 }
693
694 static void
695 test_row_reference_tree_remove (void)
696 {
697   GtkTreeIter iter0, iter1, iter2;
698   GtkTreeIter child0, child1, child2;
699   GtkTreeIter grandchild0, grandchild1, grandchild2;
700   GtkTreePath *path;
701   GtkTreeModel *model;
702   GtkTreeModelRefCount *ref_model;
703   GtkTreeRowReference *row_ref, *row_ref1, *row_ref2;
704
705   model = gtk_tree_model_ref_count_new ();
706   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
707
708   gtk_tree_store_append (GTK_TREE_STORE (model), &iter0, NULL);
709   gtk_tree_store_append (GTK_TREE_STORE (model), &child0, &iter0);
710   gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild0, &child0);
711   gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
712   gtk_tree_store_append (GTK_TREE_STORE (model), &child1, &iter1);
713   gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild1, &child1);
714   gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
715   gtk_tree_store_append (GTK_TREE_STORE (model), &child2, &iter2);
716   gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild2, &child2);
717
718   assert_entire_model_unreferenced (ref_model);
719
720   path = gtk_tree_path_new_from_indices (1, 0, 0, -1);
721   row_ref = gtk_tree_row_reference_new (model, path);
722   gtk_tree_path_free (path);
723
724   path = gtk_tree_path_new_from_indices (2, 0, -1);
725   row_ref1 = gtk_tree_row_reference_new (model, path);
726   gtk_tree_path_free (path);
727
728   path = gtk_tree_path_new_from_indices (2, -1);
729   row_ref2 = gtk_tree_row_reference_new (model, path);
730   gtk_tree_path_free (path);
731
732   assert_node_ref_count (ref_model, &iter0, 0);
733   assert_node_ref_count (ref_model, &child0, 0);
734   assert_node_ref_count (ref_model, &grandchild0, 0);
735   assert_node_ref_count (ref_model, &iter1, 1);
736   assert_node_ref_count (ref_model, &child1, 1);
737   assert_node_ref_count (ref_model, &grandchild1, 1);
738   assert_node_ref_count (ref_model, &iter2, 2);
739   assert_node_ref_count (ref_model, &child2, 1);
740   assert_node_ref_count (ref_model, &grandchild2, 0);
741
742   gtk_tree_store_remove (GTK_TREE_STORE (model), &grandchild1);
743
744   assert_node_ref_count (ref_model, &iter0, 0);
745   assert_node_ref_count (ref_model, &child0, 0);
746   assert_node_ref_count (ref_model, &grandchild0, 0);
747   assert_node_ref_count (ref_model, &iter1, 0);
748   assert_node_ref_count (ref_model, &child1, 0);
749   assert_node_ref_count (ref_model, &iter2, 2);
750   assert_node_ref_count (ref_model, &child2, 1);
751   assert_node_ref_count (ref_model, &grandchild2, 0);
752
753   gtk_tree_store_remove (GTK_TREE_STORE (model), &child2);
754
755   assert_node_ref_count (ref_model, &iter0, 0);
756   assert_node_ref_count (ref_model, &child0, 0);
757   assert_node_ref_count (ref_model, &grandchild0, 0);
758   assert_node_ref_count (ref_model, &iter1, 0);
759   assert_node_ref_count (ref_model, &child1, 0);
760   assert_node_ref_count (ref_model, &iter2, 1);
761
762   gtk_tree_store_remove (GTK_TREE_STORE (model), &iter2);
763
764   assert_entire_model_unreferenced (ref_model);
765
766   gtk_tree_row_reference_free (row_ref);
767   gtk_tree_row_reference_free (row_ref1);
768   gtk_tree_row_reference_free (row_ref2);
769
770   g_object_unref (ref_model);
771 }
772
773 static void
774 test_row_reference_tree_remove_ancestor (void)
775 {
776   GtkTreeIter iter0, iter1, iter2;
777   GtkTreeIter child0, child1, child2;
778   GtkTreeIter grandchild0, grandchild1, grandchild2;
779   GtkTreePath *path;
780   GtkTreeModel *model;
781   GtkTreeModelRefCount *ref_model;
782   GtkTreeRowReference *row_ref, *row_ref1;
783
784   model = gtk_tree_model_ref_count_new ();
785   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
786
787   gtk_tree_store_append (GTK_TREE_STORE (model), &iter0, NULL);
788   gtk_tree_store_append (GTK_TREE_STORE (model), &child0, &iter0);
789   gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild0, &child0);
790   gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
791   gtk_tree_store_append (GTK_TREE_STORE (model), &child1, &iter1);
792   gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild1, &child1);
793   gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
794   gtk_tree_store_append (GTK_TREE_STORE (model), &child2, &iter2);
795   gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild2, &child2);
796
797   assert_entire_model_unreferenced (ref_model);
798
799   path = gtk_tree_path_new_from_indices (1, 0, 0, -1);
800   row_ref = gtk_tree_row_reference_new (model, path);
801   gtk_tree_path_free (path);
802
803   path = gtk_tree_path_new_from_indices (2, 0, -1);
804   row_ref1 = gtk_tree_row_reference_new (model, path);
805   gtk_tree_path_free (path);
806
807   assert_node_ref_count (ref_model, &iter0, 0);
808   assert_node_ref_count (ref_model, &child0, 0);
809   assert_node_ref_count (ref_model, &grandchild0, 0);
810   assert_node_ref_count (ref_model, &iter1, 1);
811   assert_node_ref_count (ref_model, &child1, 1);
812   assert_node_ref_count (ref_model, &grandchild1, 1);
813   assert_node_ref_count (ref_model, &iter2, 1);
814   assert_node_ref_count (ref_model, &child2, 1);
815   assert_node_ref_count (ref_model, &grandchild2, 0);
816
817   gtk_tree_store_remove (GTK_TREE_STORE (model), &child1);
818
819   assert_node_ref_count (ref_model, &iter0, 0);
820   assert_node_ref_count (ref_model, &child0, 0);
821   assert_node_ref_count (ref_model, &grandchild0, 0);
822   assert_node_ref_count (ref_model, &iter1, 0);
823   assert_node_ref_count (ref_model, &iter2, 1);
824   assert_node_ref_count (ref_model, &child2, 1);
825   assert_node_ref_count (ref_model, &grandchild2, 0);
826
827   gtk_tree_store_remove (GTK_TREE_STORE (model), &iter2);
828
829   assert_entire_model_unreferenced (ref_model);
830
831   gtk_tree_row_reference_free (row_ref);
832   gtk_tree_row_reference_free (row_ref1);
833
834   g_object_unref (ref_model);
835 }
836
837 static void
838 test_row_reference_tree_expand (void)
839 {
840   GtkTreeIter iter0, iter1, iter2;
841   GtkTreeIter child0, child1, child2;
842   GtkTreeIter grandchild0, grandchild1, grandchild2;
843   GtkTreePath *path;
844   GtkTreeModel *model;
845   GtkTreeModelRefCount *ref_model;
846   GtkTreeRowReference *row_ref, *row_ref1, *row_ref2;
847   GtkWidget *tree_view;
848
849   model = gtk_tree_model_ref_count_new ();
850   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
851   tree_view = gtk_tree_view_new_with_model (model);
852
853   gtk_tree_store_append (GTK_TREE_STORE (model), &iter0, NULL);
854   gtk_tree_store_append (GTK_TREE_STORE (model), &child0, &iter0);
855   gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild0, &child0);
856   gtk_tree_store_append (GTK_TREE_STORE (model), &iter1, NULL);
857   gtk_tree_store_append (GTK_TREE_STORE (model), &child1, &iter1);
858   gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild1, &child1);
859   gtk_tree_store_append (GTK_TREE_STORE (model), &iter2, NULL);
860   gtk_tree_store_append (GTK_TREE_STORE (model), &child2, &iter2);
861   gtk_tree_store_append (GTK_TREE_STORE (model), &grandchild2, &child2);
862
863   assert_root_level_referenced (ref_model, 1);
864
865   gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
866
867   assert_entire_model_referenced (ref_model, 1);
868
869   path = gtk_tree_path_new_from_indices (1, 0, 0, -1);
870   row_ref = gtk_tree_row_reference_new (model, path);
871   gtk_tree_path_free (path);
872
873   path = gtk_tree_path_new_from_indices (2, 0, -1);
874   row_ref1 = gtk_tree_row_reference_new (model, path);
875   gtk_tree_path_free (path);
876
877   path = gtk_tree_path_new_from_indices (2, -1);
878   row_ref2 = gtk_tree_row_reference_new (model, path);
879   gtk_tree_path_free (path);
880
881   assert_node_ref_count (ref_model, &iter0, 1);
882   assert_node_ref_count (ref_model, &child0, 1);
883   assert_node_ref_count (ref_model, &grandchild0, 1);
884   assert_node_ref_count (ref_model, &iter1, 2);
885   assert_node_ref_count (ref_model, &child1, 2);
886   assert_node_ref_count (ref_model, &grandchild1, 2);
887   assert_node_ref_count (ref_model, &iter2, 3);
888   assert_node_ref_count (ref_model, &child2, 2);
889   assert_node_ref_count (ref_model, &grandchild2, 1);
890
891   gtk_tree_store_remove (GTK_TREE_STORE (model), &grandchild1);
892
893   assert_node_ref_count (ref_model, &iter0, 1);
894   assert_node_ref_count (ref_model, &child0, 1);
895   assert_node_ref_count (ref_model, &grandchild0, 1);
896   assert_node_ref_count (ref_model, &iter1, 1);
897   assert_node_ref_count (ref_model, &child1, 1);
898   assert_node_ref_count (ref_model, &iter2, 3);
899   assert_node_ref_count (ref_model, &child2, 2);
900   assert_node_ref_count (ref_model, &grandchild2, 1);
901
902   gtk_tree_store_remove (GTK_TREE_STORE (model), &child2);
903
904   assert_node_ref_count (ref_model, &iter0, 1);
905   assert_node_ref_count (ref_model, &child0, 1);
906   assert_node_ref_count (ref_model, &grandchild0, 1);
907   assert_node_ref_count (ref_model, &iter1, 1);
908   assert_node_ref_count (ref_model, &child1, 1);
909   assert_node_ref_count (ref_model, &iter2, 2);
910
911   gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
912
913   assert_node_ref_count (ref_model, &iter0, 1);
914   assert_node_ref_count (ref_model, &child0, 0);
915   assert_node_ref_count (ref_model, &grandchild0, 0);
916   assert_node_ref_count (ref_model, &iter1, 1);
917   assert_node_ref_count (ref_model, &child1, 0);
918   assert_node_ref_count (ref_model, &iter2, 2);
919
920   gtk_tree_store_remove (GTK_TREE_STORE (model), &iter2);
921
922   assert_node_ref_count (ref_model, &iter0, 1);
923   assert_node_ref_count (ref_model, &child0, 0);
924   assert_node_ref_count (ref_model, &grandchild0, 0);
925   assert_node_ref_count (ref_model, &iter1, 1);
926   assert_node_ref_count (ref_model, &child1, 0);
927
928   gtk_tree_row_reference_free (row_ref);
929   gtk_tree_row_reference_free (row_ref1);
930   gtk_tree_row_reference_free (row_ref2);
931
932   gtk_widget_destroy (tree_view);
933   g_object_unref (ref_model);
934 }
935
936 void
937 register_model_ref_count_tests (void)
938 {
939   /* lists (though based on GtkTreeStore) */
940   g_test_add_func ("/TreeModel/ref-count/list/no-reference",
941                    test_list_no_reference);
942   g_test_add_func ("/TreeModel/ref-count/list/reference-during-creation",
943                    test_list_reference_during_creation);
944   g_test_add_func ("/TreeModel/ref-count/list/reference-after-creation",
945                    test_list_reference_after_creation);
946   g_test_add_func ("/TreeModel/ref-count/list/reference-reordered",
947                    test_list_reference_reordered);
948
949   /* trees */
950   g_test_add_func ("/TreeModel/ref-count/tree/no-reference",
951                    test_tree_no_reference);
952   g_test_add_func ("/TreeModel/ref-count/tree/reference-during-creation",
953                    test_tree_reference_during_creation);
954   g_test_add_func ("/TreeModel/ref-count/tree/reference-after-creation",
955                    test_tree_reference_after_creation);
956   g_test_add_func ("/TreeModel/ref-count/tree/expand-all",
957                    test_tree_reference_expand_all);
958   g_test_add_func ("/TreeModel/ref-count/tree/collapse-all",
959                    test_tree_reference_collapse_all);
960   g_test_add_func ("/TreeModel/ref-count/tree/expand-collapse",
961                    test_tree_reference_expand_collapse);
962   g_test_add_func ("/TreeModel/ref-count/tree/reference-reordered",
963                    test_tree_reference_reordered);
964
965   /* row references */
966   g_test_add_func ("/TreeModel/ref-count/row-reference/list",
967                    test_row_reference_list);
968   g_test_add_func ("/TreeModel/ref-count/row-reference/list-remove",
969                    test_row_reference_list_remove);
970   g_test_add_func ("/TreeModel/ref-count/row-reference/tree",
971                    test_row_reference_tree);
972   g_test_add_func ("/TreeModel/ref-count/row-reference/tree-remove",
973                    test_row_reference_tree_remove);
974   g_test_add_func ("/TreeModel/ref-count/row-reference/tree-remove-ancestor",
975                    test_row_reference_tree_remove_ancestor);
976   g_test_add_func ("/TreeModel/ref-count/row-reference/tree-expand",
977                    test_row_reference_tree_expand);
978 }