GVariant: use GVariantTypeInfo on internal constructors
[platform/upstream/glib.git] / glib / tests / node.c
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
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, see <http://www.gnu.org/licenses/>.
16  */
17
18 /*
19  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
20  * file for a list of people on the GLib Team.  See the ChangeLog
21  * files for a list of changes.  These files are distributed with
22  * GLib at ftp://ftp.gtk.org/pub/gtk/. 
23  */
24
25 #undef G_DISABLE_ASSERT
26 #undef G_LOG_DOMAIN
27
28 #include <stdio.h>
29 #include <string.h>
30 #include <stdlib.h>
31
32 #include "glib.h"
33
34 #define C2P(c)          ((gpointer) ((long) (c)))
35 #define P2C(p)          ((gchar) ((long) (p)))
36
37 typedef struct {
38   GString *s;
39   gint count;
40 } CallbackData;
41
42 static gboolean
43 node_build_string (GNode    *node,
44                    gpointer  data)
45 {
46   CallbackData *d = data;
47
48   g_string_append_c (d->s, P2C (node->data));
49
50   d->count--;
51
52   if (d->count == 0)
53     return TRUE;
54
55   return FALSE;
56 }
57
58 typedef struct {
59     GTraverseType   traverse;
60     GTraverseFlags  flags;
61     gint            depth;
62     gint            limit;
63     const gchar    *expected;
64 } TraverseData;
65
66 static void
67 traversal_test (void)
68 {
69   GNode *root;
70   GNode *node_B;
71   GNode *node_C;
72   GNode *node_D;
73   GNode *node_E;
74   GNode *node_F;
75   GNode *node_G;
76   GNode *node_J;
77   GNode *n;
78   TraverseData orders[] = {
79     { G_PRE_ORDER,   G_TRAVERSE_ALL,       -1, -1, "ABCDEFGHIJK" },
80     { G_PRE_ORDER,   G_TRAVERSE_ALL,        1, -1, "A"           },
81     { G_PRE_ORDER,   G_TRAVERSE_ALL,        2, -1, "ABF"         },
82     { G_PRE_ORDER,   G_TRAVERSE_ALL,        3, -1, "ABCDEFG"     },
83     { G_PRE_ORDER,   G_TRAVERSE_ALL,        3, -1, "ABCDEFG"     },
84     { G_POST_ORDER,  G_TRAVERSE_ALL,       -1, -1, "CDEBHIJKGFA" },
85     { G_POST_ORDER,  G_TRAVERSE_ALL,        1, -1, "A"           },
86     { G_POST_ORDER,  G_TRAVERSE_ALL,        2, -1, "BFA"         },
87     { G_POST_ORDER,  G_TRAVERSE_ALL,        3, -1, "CDEBGFA"     },
88     { G_IN_ORDER,    G_TRAVERSE_ALL,       -1, -1, "CBDEAHGIJKF" },
89     { G_IN_ORDER,    G_TRAVERSE_ALL,        1, -1, "A"           },
90     { G_IN_ORDER,    G_TRAVERSE_ALL,        2, -1, "BAF"         },
91     { G_IN_ORDER,    G_TRAVERSE_ALL,        3, -1, "CBDEAGF"     },
92     { G_LEVEL_ORDER, G_TRAVERSE_ALL,       -1, -1, "ABFCDEGHIJK" },
93     { G_LEVEL_ORDER, G_TRAVERSE_ALL,        1, -1, "A"           },
94     { G_LEVEL_ORDER, G_TRAVERSE_ALL,        2, -1, "ABF"         },
95     { G_LEVEL_ORDER, G_TRAVERSE_ALL,        3, -1, "ABFCDEG"     },
96     { G_LEVEL_ORDER, G_TRAVERSE_LEAFS,     -1, -1, "CDEHIJK"     },
97     { G_LEVEL_ORDER, G_TRAVERSE_NON_LEAFS, -1, -1, "ABFG"        },
98     { G_PRE_ORDER,   G_TRAVERSE_ALL,       -1,  1, "A"           },
99     { G_PRE_ORDER,   G_TRAVERSE_ALL,       -1,  2, "AB"          },
100     { G_PRE_ORDER,   G_TRAVERSE_ALL,       -1,  3, "ABC"         },
101     { G_PRE_ORDER,   G_TRAVERSE_ALL,       -1,  4, "ABCD"        },
102     { G_PRE_ORDER,   G_TRAVERSE_ALL,       -1,  5, "ABCDE"       },
103     { G_PRE_ORDER,   G_TRAVERSE_ALL,       -1,  6, "ABCDEF"      },
104     { G_PRE_ORDER,   G_TRAVERSE_ALL,       -1,  7, "ABCDEFG"     },
105     { G_PRE_ORDER,   G_TRAVERSE_ALL,       -1,  8, "ABCDEFGH"    },
106     { G_PRE_ORDER,   G_TRAVERSE_ALL,       -1,  9, "ABCDEFGHI"   },
107     { G_PRE_ORDER,   G_TRAVERSE_ALL,       -1, 10, "ABCDEFGHIJ"  },
108     { G_PRE_ORDER,   G_TRAVERSE_ALL,        3,  1, "A"           },
109     { G_PRE_ORDER,   G_TRAVERSE_ALL,        3,  2, "AB"          },
110     { G_PRE_ORDER,   G_TRAVERSE_ALL,        3,  3, "ABC"         },
111     { G_PRE_ORDER,   G_TRAVERSE_ALL,        3,  4, "ABCD"        },
112     { G_PRE_ORDER,   G_TRAVERSE_ALL,        3,  5, "ABCDE"       },
113     { G_PRE_ORDER,   G_TRAVERSE_ALL,        3,  6, "ABCDEF"      },
114     { G_PRE_ORDER,   G_TRAVERSE_ALL,        3,  7, "ABCDEFG"     },
115     { G_PRE_ORDER,   G_TRAVERSE_ALL,        3,  8, "ABCDEFG"     },
116     { G_POST_ORDER,  G_TRAVERSE_ALL,       -1,  1, "C"           },
117     { G_POST_ORDER,  G_TRAVERSE_ALL,       -1,  2, "CD"          },
118     { G_POST_ORDER,  G_TRAVERSE_ALL,       -1,  3, "CDE"         },
119     { G_POST_ORDER,  G_TRAVERSE_ALL,       -1,  4, "CDEB"        },
120     { G_POST_ORDER,  G_TRAVERSE_ALL,       -1,  5, "CDEBH"       },
121     { G_POST_ORDER,  G_TRAVERSE_ALL,       -1,  6, "CDEBHI"      },
122     { G_POST_ORDER,  G_TRAVERSE_ALL,       -1,  7, "CDEBHIJ"     },
123     { G_POST_ORDER,  G_TRAVERSE_ALL,       -1,  8, "CDEBHIJK"    },
124     { G_POST_ORDER,  G_TRAVERSE_ALL,       -1,  9, "CDEBHIJKG"   },
125     { G_POST_ORDER,  G_TRAVERSE_ALL,       -1, 10, "CDEBHIJKGF"  },
126     { G_POST_ORDER,  G_TRAVERSE_ALL,        3,  1, "C"           },
127     { G_POST_ORDER,  G_TRAVERSE_ALL,        3,  2, "CD"          },
128     { G_POST_ORDER,  G_TRAVERSE_ALL,        3,  3, "CDE"         },
129     { G_POST_ORDER,  G_TRAVERSE_ALL,        3,  4, "CDEB"        },
130     { G_POST_ORDER,  G_TRAVERSE_ALL,        3,  5, "CDEBG"       },
131     { G_POST_ORDER,  G_TRAVERSE_ALL,        3,  6, "CDEBGF"      },
132     { G_POST_ORDER,  G_TRAVERSE_ALL,        3,  7, "CDEBGFA"     },
133     { G_POST_ORDER,  G_TRAVERSE_ALL,        3,  8, "CDEBGFA"     },
134     { G_IN_ORDER,    G_TRAVERSE_ALL,       -1,  1, "C"           },
135     { G_IN_ORDER,    G_TRAVERSE_ALL,       -1,  2, "CB"          },
136     { G_IN_ORDER,    G_TRAVERSE_ALL,       -1,  3, "CBD"         },
137     { G_IN_ORDER,    G_TRAVERSE_ALL,       -1,  4, "CBDE"        },
138     { G_IN_ORDER,    G_TRAVERSE_ALL,       -1,  5, "CBDEA"       },
139     { G_IN_ORDER,    G_TRAVERSE_ALL,       -1,  6, "CBDEAH"      },
140     { G_IN_ORDER,    G_TRAVERSE_ALL,       -1,  7, "CBDEAHG"     },
141     { G_IN_ORDER,    G_TRAVERSE_ALL,       -1,  8, "CBDEAHGI"    },
142     { G_IN_ORDER,    G_TRAVERSE_ALL,       -1,  9, "CBDEAHGIJ"   },
143     { G_IN_ORDER,    G_TRAVERSE_ALL,       -1, 10, "CBDEAHGIJK"  },
144     { G_IN_ORDER,    G_TRAVERSE_ALL,        3,  1, "C"           },
145     { G_IN_ORDER,    G_TRAVERSE_ALL,        3,  2, "CB"          },
146     { G_IN_ORDER,    G_TRAVERSE_ALL,        3,  3, "CBD"         },
147     { G_IN_ORDER,    G_TRAVERSE_ALL,        3,  4, "CBDE"        },
148     { G_IN_ORDER,    G_TRAVERSE_ALL,        3,  5, "CBDEA"       },
149     { G_IN_ORDER,    G_TRAVERSE_ALL,        3,  6, "CBDEAG"      },
150     { G_IN_ORDER,    G_TRAVERSE_ALL,        3,  7, "CBDEAGF"     },
151     { G_IN_ORDER,    G_TRAVERSE_ALL,        3,  8, "CBDEAGF"     },
152     { G_LEVEL_ORDER, G_TRAVERSE_ALL,       -1,  1, "A"           },
153     { G_LEVEL_ORDER, G_TRAVERSE_ALL,       -1,  2, "AB"          },
154     { G_LEVEL_ORDER, G_TRAVERSE_ALL,       -1,  3, "ABF"         },
155     { G_LEVEL_ORDER, G_TRAVERSE_ALL,       -1,  4, "ABFC"        },
156     { G_LEVEL_ORDER, G_TRAVERSE_ALL,       -1,  5, "ABFCD"       },
157     { G_LEVEL_ORDER, G_TRAVERSE_ALL,       -1,  6, "ABFCDE"      },
158     { G_LEVEL_ORDER, G_TRAVERSE_ALL,       -1,  7, "ABFCDEG"     },
159     { G_LEVEL_ORDER, G_TRAVERSE_ALL,       -1,  8, "ABFCDEGH"    },
160     { G_LEVEL_ORDER, G_TRAVERSE_ALL,       -1,  9, "ABFCDEGHI"   },
161     { G_LEVEL_ORDER, G_TRAVERSE_ALL,       -1, 10, "ABFCDEGHIJ"  },
162     { G_LEVEL_ORDER, G_TRAVERSE_ALL,        3,  1, "A"           },
163     { G_LEVEL_ORDER, G_TRAVERSE_ALL,        3,  2, "AB"          },
164     { G_LEVEL_ORDER, G_TRAVERSE_ALL,        3,  3, "ABF"         },
165     { G_LEVEL_ORDER, G_TRAVERSE_ALL,        3,  4, "ABFC"        },
166     { G_LEVEL_ORDER, G_TRAVERSE_ALL,        3,  5, "ABFCD"       },
167     { G_LEVEL_ORDER, G_TRAVERSE_ALL,        3,  6, "ABFCDE"      },
168     { G_LEVEL_ORDER, G_TRAVERSE_ALL,        3,  7, "ABFCDEG"     },
169     { G_LEVEL_ORDER, G_TRAVERSE_ALL,        3,  8, "ABFCDEG"     },
170   };
171   gint i;
172   CallbackData data;
173
174   root = g_node_new (C2P ('A'));
175   node_B = g_node_new (C2P ('B'));
176   g_node_append (root, node_B);
177   g_node_append_data (node_B, C2P ('E'));
178   g_node_prepend_data (node_B, C2P ('C'));
179   node_D = g_node_new (C2P ('D'));
180   g_node_insert (node_B, 1, node_D);
181   node_F = g_node_new (C2P ('F'));
182   g_node_append (root, node_F);
183   node_G = g_node_new (C2P ('G'));
184   g_node_append (node_F, node_G);
185   node_J = g_node_new (C2P ('J'));
186   g_node_prepend (node_G, node_J);
187   g_node_insert (node_G, 42, g_node_new (C2P ('K')));
188   g_node_insert_data (node_G, 0, C2P ('H'));
189   g_node_insert (node_G, 1, g_node_new (C2P ('I')));
190
191   /* we have built:                    A
192    *                                 /   \
193    *                               B       F
194    *                             / | \       \
195    *                           C   D   E       G
196    *                                         / /\ \
197    *                                        H I J  K
198    *
199    * for in-order traversal, 'G' is considered to be the "left"
200    * child of 'F', which will cause 'F' to be the last node visited.
201    */
202
203   node_C = node_B->children;
204   node_E = node_D->next;
205
206   n = g_node_last_sibling (node_C);
207   g_assert (n == node_E);
208   n = g_node_last_sibling (node_D);
209   g_assert (n == node_E);
210   n = g_node_last_sibling (node_E);
211   g_assert (n == node_E);
212
213   data.s = g_string_new ("");  
214   for (i = 0; i < G_N_ELEMENTS (orders); i++)
215     {
216       g_string_set_size (data.s, 0);
217       data.count = orders[i].limit;
218       g_node_traverse (root, orders[i].traverse, orders[i].flags, orders[i].depth, node_build_string, &data);
219       g_assert_cmpstr (data.s->str, ==,  orders[i].expected);
220     }
221
222   g_node_reverse_children (node_B);
223   g_node_reverse_children (node_G);
224
225   g_string_set_size (data.s, 0);
226   data.count = -1;
227   g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, node_build_string, &data);
228   g_assert_cmpstr (data.s->str, ==, "ABFEDCGKJIH");
229   
230   g_node_append (node_D, g_node_new (C2P ('L')));
231   g_node_insert (node_D, -1, g_node_new (C2P ('M')));
232
233   g_string_set_size (data.s, 0);
234   data.count = -1;
235   g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, node_build_string, &data);
236   g_assert_cmpstr (data.s->str, ==, "ABFEDCGLMKJIH");
237
238   g_node_destroy (root);
239   g_string_free (data.s, TRUE);
240 }
241
242 static void
243 construct_test (void)
244 {
245   GNode *root;
246   GNode *node;
247   GNode *node_B;
248   GNode *node_D;
249   GNode *node_F;
250   GNode *node_G;
251   GNode *node_J;
252   GNode *node_H;
253   guint i;
254
255   root = g_node_new (C2P ('A'));
256   g_assert_cmpint (g_node_depth (root), ==, 1);
257   g_assert_cmpint (g_node_max_height (root), ==, 1);
258
259   node_B = g_node_new (C2P ('B'));
260   g_node_append (root, node_B);
261   g_assert (root->children == node_B);
262
263   g_node_append_data (node_B, C2P ('E'));
264   g_node_prepend_data (node_B, C2P ('C'));
265   node_D = g_node_new (C2P ('D'));
266   g_node_insert (node_B, 1, node_D);
267
268   node_F = g_node_new (C2P ('F'));
269   g_node_append (root, node_F);
270   g_assert (root->children->next == node_F);
271
272   node_G = g_node_new (C2P ('G'));
273   g_node_append (node_F, node_G);
274   node_J = g_node_new (C2P ('J'));
275   g_node_insert_after (node_G, NULL, node_J);
276   g_node_insert (node_G, 42, g_node_new (C2P ('K')));
277   node_H = g_node_new (C2P ('H'));
278   g_node_insert_after (node_G, NULL, node_H);
279   g_node_insert (node_G, 1, g_node_new (C2P ('I')));
280
281   /* we have built:                    A
282    *                                 /   \
283    *                               B       F
284    *                             / | \       \
285    *                           C   D   E       G
286    *                                         / /\ \
287    *                                       H  I  J  K
288    */
289   g_assert_cmpint (g_node_depth (root), ==, 1);
290   g_assert_cmpint (g_node_max_height (root), ==, 4);
291   g_assert_cmpint (g_node_depth (node_G->children->next), ==, 4);
292   g_assert_cmpint (g_node_n_nodes (root, G_TRAVERSE_LEAFS), ==, 7);
293   g_assert_cmpint (g_node_n_nodes (root, G_TRAVERSE_NON_LEAFS), ==, 4);
294   g_assert_cmpint (g_node_n_nodes (root, G_TRAVERSE_ALL), ==, 11);
295   g_assert_cmpint (g_node_max_height (node_F), ==, 3);
296   g_assert_cmpint (g_node_n_children (node_G), ==, 4);
297   g_assert (g_node_find_child (root, G_TRAVERSE_ALL, C2P ('F')) == node_F);
298   g_assert (g_node_find_child (node_G, G_TRAVERSE_LEAFS, C2P ('H')) == node_H);
299   g_assert (g_node_find_child (root, G_TRAVERSE_ALL, C2P ('H')) == NULL);
300   g_assert (g_node_find (root, G_LEVEL_ORDER, G_TRAVERSE_NON_LEAFS, C2P ('I')) == NULL);
301   g_assert (g_node_find (root, G_IN_ORDER, G_TRAVERSE_LEAFS, C2P ('J')) == node_J);
302
303   for (i = 0; i < g_node_n_children (node_B); i++)
304     {
305       node = g_node_nth_child (node_B, i);
306       g_assert_cmpint (P2C (node->data), ==, ('C' + i));
307     }
308
309   for (i = 0; i < g_node_n_children (node_G); i++)
310     g_assert_cmpint (g_node_child_position (node_G, g_node_nth_child (node_G, i)), ==, i);
311
312   g_node_destroy (root);
313 }
314
315 static void
316 allocation_test (void)
317 {
318   GNode *root;
319   GNode *node;
320   gint i;
321
322   root = g_node_new (NULL);
323   node = root;
324
325   for (i = 0; i < 2048; i++)
326     {
327       g_node_append (node, g_node_new (NULL));
328       if ((i % 5) == 4)
329         node = node->children->next;
330     }
331   g_assert_cmpint (g_node_max_height (root), >, 100);
332   g_assert_cmpint (g_node_n_nodes (root, G_TRAVERSE_ALL), ==, 1 + 2048);
333
334   g_node_destroy (root);
335 }
336
337
338 static void
339 misc_test (void)
340 {
341   GNode *root;
342   GNode *node_B;
343   GNode *node_C;
344   GNode *node_D;
345   GNode *node_E;
346   CallbackData data;
347
348   root = g_node_new (C2P ('A'));
349   node_B = g_node_new (C2P ('B'));
350   g_node_append (root, node_B);
351   node_D = g_node_new (C2P ('D'));
352   g_node_append (root, node_D);
353   node_C = g_node_new (C2P ('C'));
354   g_node_insert_after (root, node_B, node_C);
355   node_E = g_node_new (C2P ('E'));
356   g_node_append (node_C, node_E);
357
358   g_assert (g_node_get_root (node_E) == root);
359   g_assert (g_node_is_ancestor (root, node_B));
360   g_assert (g_node_is_ancestor (root, node_E));
361   g_assert (!g_node_is_ancestor (node_B, node_D));
362   g_assert (g_node_first_sibling (node_D) == node_B);
363   g_assert (g_node_first_sibling (node_E) == node_E);
364   g_assert (g_node_first_sibling (root) == root);
365   g_assert_cmpint (g_node_child_index (root, C2P ('B')), ==, 0);
366   g_assert_cmpint (g_node_child_index (root, C2P ('C')), ==, 1);
367   g_assert_cmpint (g_node_child_index (root, C2P ('D')), ==, 2);
368   g_assert_cmpint (g_node_child_index (root, C2P ('E')), ==, -1);
369
370   data.s = g_string_new ("");
371   data.count = -1;
372   g_node_children_foreach (root, G_TRAVERSE_ALL, (GNodeForeachFunc)node_build_string, &data);
373   g_assert_cmpstr (data.s->str, ==, "BCD");
374
375   g_string_set_size (data.s, 0);
376   data.count = -1;
377   g_node_children_foreach (root, G_TRAVERSE_LEAVES, (GNodeForeachFunc)node_build_string, &data);
378   g_assert_cmpstr (data.s->str, ==, "BD");
379
380   g_string_set_size (data.s, 0);
381   data.count = -1;
382   g_node_children_foreach (root, G_TRAVERSE_NON_LEAVES, (GNodeForeachFunc)node_build_string, &data);
383   g_assert_cmpstr (data.s->str, ==, "C");
384   g_string_free (data.s, TRUE);
385
386   g_node_destroy (root);
387 }
388
389 static gboolean
390 check_order (GNode    *node,
391              gpointer  data)
392 {
393   gchar **expected = data;
394   gchar d;
395
396   d = GPOINTER_TO_INT (node->data);
397   g_assert_cmpint (d, ==, **expected);
398   (*expected)++;
399
400   return FALSE;
401 }
402
403 static void
404 unlink_test (void)
405 {
406   GNode *root;
407   GNode *node;
408   GNode *bnode;
409   GNode *cnode;
410   gchar *expected;
411
412   /*
413    *        -------- a --------
414    *       /         |          \
415    *     b           c           d
416    *   / | \       / | \       / | \
417    * e   f   g   h   i   j   k   l   m
418    *
419    */
420
421   root = g_node_new (C2P ('a'));
422   node = bnode = g_node_append_data (root, C2P ('b'));
423   g_node_append_data (node, C2P ('e'));
424   g_node_append_data (node, C2P ('f'));
425   g_node_append_data (node, C2P ('g'));
426
427   node = cnode = g_node_append_data (root, C2P ('c'));
428   g_node_append_data (node, C2P ('h'));
429   g_node_append_data (node, C2P ('i'));
430   g_node_append_data (node, C2P ('j'));
431
432   node = g_node_append_data (root, C2P ('d'));
433   g_node_append_data (node, C2P ('k'));
434   g_node_append_data (node, C2P ('l'));
435   g_node_append_data (node, C2P ('m'));
436
437   g_node_unlink (cnode);
438
439   expected = "abdefgklm";
440   g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, check_order, &expected);
441
442   expected = "abd";
443   g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_ALL, 1, check_order, &expected);
444
445   expected = "chij";
446   g_node_traverse (cnode, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, check_order, &expected);
447
448   g_node_destroy (bnode);
449
450   expected = "adklm";
451   g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, check_order, &expected);
452
453   g_node_destroy (root);
454   g_node_destroy (cnode);
455 }
456
457 static gpointer
458 copy_up (gconstpointer src,
459          gpointer      data)
460 {
461   gchar l, u;
462
463   l = GPOINTER_TO_INT (src);
464   u = g_ascii_toupper (l);
465
466   return GINT_TO_POINTER ((int)u);
467 }
468
469 static void
470 copy_test (void)
471 {
472   GNode *root;
473   GNode *copy;
474   gchar *expected;
475
476   root = g_node_new (C2P ('a'));
477   g_node_append_data (root, C2P ('b'));
478   g_node_append_data (root, C2P ('c'));
479   g_node_append_data (root, C2P ('d'));
480
481   expected = "abcd";
482   g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, check_order, &expected);
483
484   copy = g_node_copy (root);
485
486   expected = "abcd";
487   g_node_traverse (copy, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, check_order, &expected);
488
489   g_node_destroy (copy);
490
491   copy = g_node_copy_deep (root, copy_up, NULL);
492
493   expected = "ABCD";
494   g_node_traverse (copy, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, check_order, &expected);
495
496   g_node_destroy (copy);
497
498   g_node_destroy (root);
499 }
500
501 int
502 main (int   argc,
503       char *argv[])
504 {
505   g_test_init (&argc, &argv, NULL);
506
507   g_test_add_func ("/node/allocation", allocation_test);
508   g_test_add_func ("/node/construction", construct_test);
509   g_test_add_func ("/node/traversal", traversal_test);
510   g_test_add_func ("/node/misc", misc_test);
511   g_test_add_func ("/node/unlink", unlink_test);
512   g_test_add_func ("/node/copy", copy_test);
513
514   return g_test_run ();
515 }
516