gkdbus: Fix underflow and unreachable code bug
[platform/upstream/glib.git] / gio / tests / defaultvalue.c
1 /* GIO default value tests
2  * Copyright (C) 2013 Red Hat, Inc.
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <string.h>
21 #include <gio/gio.h>
22
23 static void
24 check_property (const char *output,
25                 GParamSpec *pspec,
26                 GValue *value)
27 {
28   GValue default_value = G_VALUE_INIT;
29   char *v, *dv, *msg;
30
31   if (g_param_value_defaults (pspec, value))
32       return;
33
34   g_param_value_set_default (pspec, &default_value);
35
36   v = g_strdup_value_contents (value);
37   dv = g_strdup_value_contents (&default_value);
38
39   msg = g_strdup_printf ("%s %s.%s: %s != %s\n",
40                          output,
41                          g_type_name (pspec->owner_type),
42                          pspec->name,
43                          dv, v);
44   g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
45   g_free (msg);
46
47   g_free (v);
48   g_free (dv);
49   g_value_unset (&default_value);
50 }
51
52 static void
53 test_type (gconstpointer data)
54 {
55   GObjectClass *klass;
56   GObject *instance;
57   GParamSpec **pspecs;
58   guint n_pspecs, i;
59   GType type;
60
61   type = * (GType *) data;
62
63   if (g_type_is_a (type, G_TYPE_APP_INFO_MONITOR))
64     {
65       g_test_skip ("singleton");
66       return;
67     }
68
69   if (g_type_is_a (type, G_TYPE_BINDING) ||
70       g_type_is_a (type, G_TYPE_BUFFERED_INPUT_STREAM) ||
71       g_type_is_a (type, G_TYPE_BUFFERED_OUTPUT_STREAM) ||
72       g_type_is_a (type, G_TYPE_CHARSET_CONVERTER) ||
73       g_type_is_a (type, G_TYPE_DBUS_ACTION_GROUP) ||
74       g_type_is_a (type, G_TYPE_DBUS_CONNECTION) ||
75       g_type_is_a (type, G_TYPE_DBUS_OBJECT_MANAGER_CLIENT) ||
76       g_type_is_a (type, G_TYPE_DBUS_OBJECT_MANAGER_SERVER) ||
77       g_type_is_a (type, G_TYPE_DBUS_PROXY) ||
78       g_type_is_a (type, G_TYPE_DBUS_SERVER) ||
79       g_type_is_a (type, G_TYPE_FILTER_OUTPUT_STREAM) ||
80       g_type_is_a (type, G_TYPE_FILTER_INPUT_STREAM) ||
81       g_type_is_a (type, G_TYPE_INET_ADDRESS) ||
82       g_type_is_a (type, G_TYPE_INET_SOCKET_ADDRESS) ||
83       g_type_is_a (type, G_TYPE_PROPERTY_ACTION) ||
84       g_type_is_a (type, G_TYPE_SETTINGS) ||
85       g_type_is_a (type, G_TYPE_SOCKET_CONNECTION) ||
86       g_type_is_a (type, G_TYPE_SIMPLE_IO_STREAM) ||
87       g_type_is_a (type, G_TYPE_THEMED_ICON) ||
88       FALSE)
89     {
90       g_test_skip ("mandatory construct params");
91       return;
92     }
93
94   if (g_type_is_a (type, G_TYPE_DBUS_MENU_MODEL) ||
95       g_type_is_a (type, G_TYPE_DBUS_METHOD_INVOCATION))
96     {
97       g_test_skip ("crash in finalize");
98       return;
99     }
100
101   if (g_type_is_a (type, G_TYPE_FILE_ENUMERATOR) ||
102       g_type_is_a (type, G_TYPE_FILE_IO_STREAM))
103     {
104       g_test_skip ("should be abstract");
105       return;
106     }
107
108   klass = g_type_class_ref (type);
109   instance = g_object_new (type, NULL);
110
111   if (G_IS_INITABLE (instance) &&
112       !g_initable_init (G_INITABLE (instance), NULL, NULL))
113     {
114       g_test_skip ("initialization failed");
115       g_object_unref (instance);
116       g_type_class_unref (klass);
117       return;
118     }
119
120   if (g_type_is_a (type, G_TYPE_INITIALLY_UNOWNED))
121     g_object_ref_sink (instance);
122
123   pspecs = g_object_class_list_properties (klass, &n_pspecs);
124   for (i = 0; i < n_pspecs; ++i)
125     {
126       GParamSpec *pspec = pspecs[i];
127       GValue value = G_VALUE_INIT;
128
129       if (pspec->owner_type != type)
130         continue;
131
132       if ((pspec->flags & G_PARAM_READABLE) == 0)
133         continue;
134
135       if (g_type_is_a (type, G_TYPE_APPLICATION) &&
136           (strcmp (pspec->name, "is-remote") == 0))
137         {
138           g_test_message ("skipping GApplication:is-remote");
139           continue;
140         }
141
142       if (g_type_is_a (type, G_TYPE_PROXY_ADDRESS_ENUMERATOR) &&
143           (strcmp (pspec->name, "proxy-resolver") == 0))
144         {
145           g_test_message ("skipping GProxyAddressEnumerator:proxy-resolver");
146           continue;
147         }
148
149       if (g_type_is_a (type, G_TYPE_SOCKET_CLIENT) &&
150           (strcmp (pspec->name, "proxy-resolver") == 0))
151         {
152           g_test_message ("skipping GSocketClient:proxy-resolver");
153           continue;
154         }
155
156       if (g_test_verbose ())
157         g_printerr ("Property %s.%s\n", g_type_name (pspec->owner_type), pspec->name);
158       g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
159       g_object_get_property (instance, pspec->name, &value);
160       check_property ("Property", pspec, &value);
161       g_value_unset (&value);
162     }
163   g_free (pspecs);
164   g_object_unref (instance);
165   g_type_class_unref (klass);
166 }
167
168 static GType *all_registered_types;
169
170 static const GType *
171 list_all_types (void)
172 {
173   if (!all_registered_types)
174     {
175       GType *tp;
176       all_registered_types = g_new0 (GType, 1000);
177       tp = all_registered_types;
178 #include "giotypefuncs.inc"
179       *tp = 0;
180     }
181
182   return all_registered_types;
183 }
184
185 int
186 main (int argc, char **argv)
187 {
188   const GType *otypes;
189   guint i;
190   GTestDBus *bus;
191   gint result;
192
193   g_setenv ("GIO_USE_VFS", "local", TRUE);
194   g_setenv ("GSETTINGS_BACKEND", "memory", TRUE);
195
196   /* Disable deprecation warnings when we poke at deprecated properties */
197   g_setenv ("G_ENABLE_DIAGNOSTIC", "0", TRUE);
198
199   g_test_init (&argc, &argv, NULL);
200
201   /* Create one test bus for all tests, as we have a lot of very small
202    * and quick tests.
203    */
204   bus = g_test_dbus_new (G_TEST_DBUS_NONE);
205   g_test_dbus_up (bus);
206
207   otypes = list_all_types ();
208   for (i = 0; otypes[i]; i++)
209     {
210       gchar *testname;
211
212       if (!G_TYPE_IS_CLASSED (otypes[i]))
213         continue;
214
215       if (G_TYPE_IS_ABSTRACT (otypes[i]))
216         continue;
217
218       if (!g_type_is_a (otypes[i], G_TYPE_OBJECT))
219         continue;
220
221       testname = g_strdup_printf ("/Default Values/%s",
222                                   g_type_name (otypes[i]));
223       g_test_add_data_func (testname, &otypes[i], test_type);
224       g_free (testname);
225     }
226
227   result = g_test_run ();
228
229   g_test_dbus_down (bus);
230   g_object_unref (bus);
231
232   return result;
233 }