1 #include <glib.h>
2 #include <glib-object.h>
3
4 #include <gladeui/glade-app.h>
5
6 /* Avoid warnings from GVFS-RemoteVolumeMonitor */
7 static gboolean
ignore_gvfs_warning(const gchar * log_domain,GLogLevelFlags log_level,const gchar * message,gpointer user_data)8 ignore_gvfs_warning (const gchar *log_domain,
9 GLogLevelFlags log_level,
10 const gchar *message,
11 gpointer user_data)
12 {
13 if (g_strcmp0 (log_domain, "GVFS-RemoteVolumeMonitor") == 0)
14 return FALSE;
15
16 return TRUE;
17 }
18
19 static gboolean
main_loop_quit_cb(gpointer data)20 main_loop_quit_cb (gpointer data)
21 {
22 gtk_main_quit ();
23
24 return FALSE;
25 }
26
27 static void
check_finalized(gpointer data,GObject * where_the_object_was)28 check_finalized (gpointer data,
29 GObject *where_the_object_was)
30 {
31 gboolean *did_finalize = (gboolean *)data;
32
33 *did_finalize = TRUE;
34 }
35
36 static void
test_create_widget(gconstpointer data)37 test_create_widget (gconstpointer data)
38 {
39 GladeWidgetAdaptor *adaptor = (GladeWidgetAdaptor *)data;
40 GladeWidget *widget;
41 GObject *object;
42 gboolean widget_finalized = FALSE;
43 gboolean object_finalized = FALSE;
44
45 g_test_log_set_fatal_handler (ignore_gvfs_warning, NULL);
46
47
48 widget = glade_widget_adaptor_create_widget (adaptor, FALSE, NULL);
49 g_assert (GLADE_IS_WIDGET (widget));
50
51 object = glade_widget_get_object (widget);
52 g_assert (G_IS_OBJECT (object));
53
54 g_object_weak_ref (G_OBJECT (widget), check_finalized, &widget_finalized);
55 g_object_weak_ref (G_OBJECT (object), check_finalized, &object_finalized);
56
57 /* filechoosers hold a reference until an async operation is complete */
58 if (GTK_IS_FILE_CHOOSER (object))
59 {
60 g_timeout_add (2000, main_loop_quit_cb, NULL);
61 gtk_main();
62 }
63 /* Our plugin code adds an idle when cell renderers are created */
64 else if (GTK_IS_CELL_RENDERER (object))
65 {
66 g_timeout_add (50, main_loop_quit_cb, NULL);
67 gtk_main();
68 }
69
70 /* Get rid of the GladeWidget and assert that it finalizes along
71 * with it's internal object
72 */
73 g_object_unref (widget);
74
75 g_assert (widget_finalized);
76 g_assert (object_finalized);
77 }
78
79 static gint
adaptor_cmp(gconstpointer a,gconstpointer b)80 adaptor_cmp (gconstpointer a, gconstpointer b)
81 {
82 return g_strcmp0 (glade_widget_adaptor_get_name ((gpointer)a),
83 glade_widget_adaptor_get_name ((gpointer)b));
84 }
85
86 int
main(int argc,char * argv[])87 main (int argc,
88 char *argv[])
89 {
90 GList *adaptors, *l;
91
92 gtk_test_init (&argc, &argv, NULL);
93
94 glade_init ();
95 glade_app_get ();
96
97 adaptors = g_list_sort (glade_widget_adaptor_list_adaptors (), adaptor_cmp);
98
99 for (l = adaptors; l; l = l->next)
100 {
101 GladeWidgetAdaptor *adaptor = l->data;
102 GType adaptor_type;
103
104 adaptor_type = glade_widget_adaptor_get_object_type (adaptor);
105
106 if (G_TYPE_IS_INSTANTIATABLE (adaptor_type) && !G_TYPE_IS_ABSTRACT (adaptor_type) &&
107 /* FIXME: FileChooserButton leaks a GTask which will crash in the following test */
108 adaptor_type != GTK_TYPE_FILE_CHOOSER_BUTTON &&
109 /* FIXME: GtkRecentChooser tries to remove an unknown source id */
110 !g_type_is_a (adaptor_type, GTK_TYPE_RECENT_CHOOSER) &&
111 /* FIXME: can not create a themed icon without a name */
112 !g_type_is_a (adaptor_type, G_TYPE_THEMED_ICON) &&
113 /* FIXME: Dialogs now use a headerbar by default making gtk give a warning when adding a widget to the action area */
114 !g_type_is_a (adaptor_type, GTK_TYPE_DIALOG) &&
115 /* FIXME: The same goes for assistant */
116 !g_type_is_a (adaptor_type, GTK_TYPE_ASSISTANT) &&
117 /* FIXME: GtkPopoverMenu gives a few warnings */
118 !g_type_is_a (adaptor_type, GTK_TYPE_POPOVER_MENU))
119 {
120 gchar *test_path = g_strdup_printf ("/CreateWidget/%s", glade_widget_adaptor_get_name (adaptor));
121
122 g_test_add_data_func (test_path, adaptor, test_create_widget);
123
124 g_free (test_path);
125 }
126 }
127 g_list_free (adaptors);
128
129 return g_test_run ();
130 }
131