Branch data Line data Source code
1 : : /* GObject - GLib Type, Object, Parameter and Signal Library
2 : : * Copyright (C) 2001, 2003 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
17 : : * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 : : */
19 : :
20 : : #include <glib-object.h>
21 : :
22 : : #include "testcommon.h"
23 : : #include "testmodule.h"
24 : :
25 : : /* This test tests getting the default vtable for an interface
26 : : * and the initialization and finalization of such default
27 : : * interfaces.
28 : : *
29 : : * We test this both for static and for dynamic interfaces.
30 : : */
31 : :
32 : : /**********************************************************************
33 : : * Static interface tests
34 : : **********************************************************************/
35 : :
36 : : typedef struct _TestStaticIfaceClass TestStaticIfaceClass;
37 : :
38 : : struct _TestStaticIfaceClass
39 : : {
40 : : GTypeInterface base_iface;
41 : : guint val;
42 : : };
43 : :
44 : : GType test_static_iface_get_type (void);
45 : : #define TEST_TYPE_STATIC_IFACE (test_static_iface_get_type ())
46 : :
47 : : static void
48 : 1 : test_static_iface_default_init (TestStaticIfaceClass *iface)
49 : : {
50 : 1 : iface->val = 42;
51 : 1 : }
52 : :
53 : 4 : DEFINE_IFACE (TestStaticIface, test_static_iface,
54 : : NULL, test_static_iface_default_init)
55 : :
56 : : static void
57 : 1 : test_static_iface (void)
58 : : {
59 : : TestStaticIfaceClass *static_iface;
60 : :
61 : : /* Not loaded until we call ref for the first time */
62 : 1 : static_iface = g_type_default_interface_peek (TEST_TYPE_STATIC_IFACE);
63 : 1 : g_assert_null (static_iface);
64 : :
65 : : /* Ref loads */
66 : 1 : static_iface = g_type_default_interface_ref (TEST_TYPE_STATIC_IFACE);
67 : 1 : g_assert_nonnull (static_iface);
68 : 1 : g_assert_cmpint (static_iface->val, ==, 42);
69 : :
70 : : /* Peek then works */
71 : 1 : static_iface = g_type_default_interface_peek (TEST_TYPE_STATIC_IFACE);
72 : 1 : g_assert_nonnull (static_iface);
73 : 1 : g_assert_cmpint (static_iface->val, ==, 42);
74 : :
75 : : /* Unref does nothing */
76 : 1 : g_type_default_interface_unref (static_iface);
77 : :
78 : : /* And peek still works */
79 : 1 : static_iface = g_type_default_interface_peek (TEST_TYPE_STATIC_IFACE);
80 : 1 : g_assert_nonnull (static_iface);
81 : 1 : g_assert_cmpint (static_iface->val, ==, 42);
82 : 1 : }
83 : :
84 : : /**********************************************************************
85 : : * Dynamic interface tests
86 : : **********************************************************************/
87 : :
88 : : typedef struct _TestDynamicIfaceClass TestDynamicIfaceClass;
89 : :
90 : : struct _TestDynamicIfaceClass
91 : : {
92 : : GTypeInterface base_iface;
93 : : guint val;
94 : : };
95 : :
96 : : static GType test_dynamic_iface_type;
97 : : static gboolean dynamic_iface_init = FALSE;
98 : :
99 : : #define TEST_TYPE_DYNAMIC_IFACE (test_dynamic_iface_type)
100 : :
101 : : static void
102 : 1 : test_dynamic_iface_default_init (TestStaticIfaceClass *iface)
103 : : {
104 : 1 : dynamic_iface_init = TRUE;
105 : 1 : iface->val = 42;
106 : 1 : }
107 : :
108 : : static void
109 : 0 : test_dynamic_iface_default_finalize (TestStaticIfaceClass *iface)
110 : : {
111 : 0 : dynamic_iface_init = FALSE;
112 : 0 : }
113 : :
114 : : static void
115 : 2 : test_dynamic_iface_register (GTypeModule *module)
116 : : {
117 : 2 : const GTypeInfo iface_info =
118 : : {
119 : : sizeof (TestDynamicIfaceClass),
120 : : (GBaseInitFunc) NULL,
121 : : (GBaseFinalizeFunc) NULL,
122 : : (GClassInitFunc) test_dynamic_iface_default_init,
123 : : (GClassFinalizeFunc) test_dynamic_iface_default_finalize,
124 : : NULL,
125 : : 0,
126 : : 0,
127 : : NULL,
128 : : NULL
129 : : };
130 : :
131 : 2 : test_dynamic_iface_type =
132 : 2 : g_type_module_register_type (module, G_TYPE_INTERFACE,
133 : : "TestDynamicIface", &iface_info, 0);
134 : 2 : }
135 : :
136 : : static void
137 : 2 : module_register (GTypeModule *module)
138 : : {
139 : 2 : test_dynamic_iface_register (module);
140 : 2 : }
141 : :
142 : : static void
143 : 1 : test_dynamic_iface (void)
144 : : {
145 : : TestDynamicIfaceClass *dynamic_iface;
146 : :
147 : 1 : test_module_new (module_register);
148 : :
149 : : /* Not loaded until we call ref for the first time */
150 : 1 : dynamic_iface = g_type_default_interface_peek (TEST_TYPE_DYNAMIC_IFACE);
151 : 1 : g_assert_null (dynamic_iface);
152 : :
153 : : /* Ref loads */
154 : 1 : dynamic_iface = g_type_default_interface_ref (TEST_TYPE_DYNAMIC_IFACE);
155 : 1 : g_assert_true (dynamic_iface_init);
156 : 1 : g_assert_nonnull (dynamic_iface);
157 : 1 : g_assert_cmpint (dynamic_iface->val, ==, 42);
158 : :
159 : : /* Peek then works */
160 : 1 : dynamic_iface = g_type_default_interface_peek (TEST_TYPE_DYNAMIC_IFACE);
161 : 1 : g_assert_nonnull (dynamic_iface);
162 : 1 : g_assert_cmpint (dynamic_iface->val, ==, 42);
163 : :
164 : : /* Unref causes finalize */
165 : 1 : g_type_default_interface_unref (dynamic_iface);
166 : : #if 0
167 : : /* Disabled as unloading dynamic types is disabled.
168 : : * See https://gitlab.gnome.org/GNOME/glib/-/issues/667 */
169 : : g_assert_false (dynamic_iface_init);
170 : : #endif
171 : :
172 : : /* Peek returns NULL */
173 : 1 : dynamic_iface = g_type_default_interface_peek (TEST_TYPE_DYNAMIC_IFACE);
174 : : #if 0
175 : : /* Disabled as unloading dynamic types is disabled.
176 : : * See https://gitlab.gnome.org/GNOME/glib/-/issues/667 */
177 : : g_assert_null (dynamic_iface);
178 : : #endif
179 : :
180 : : /* Ref reloads */
181 : 1 : dynamic_iface = g_type_default_interface_ref (TEST_TYPE_DYNAMIC_IFACE);
182 : 1 : g_assert_true (dynamic_iface_init);
183 : 1 : g_assert_nonnull (dynamic_iface);
184 : 1 : g_assert_cmpint (dynamic_iface->val, ==, 42);
185 : :
186 : : /* And Unref causes finalize once more*/
187 : 1 : g_type_default_interface_unref (dynamic_iface);
188 : : #if 0
189 : : /* Disabled as unloading dynamic types is disabled.
190 : : * See https://gitlab.gnome.org/GNOME/glib/-/issues/667 */
191 : : g_assert_false (dynamic_iface_init);
192 : : #endif
193 : 1 : }
194 : :
195 : : int
196 : 1 : main (int argc,
197 : : char *argv[])
198 : : {
199 : 1 : g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) |
200 : 1 : G_LOG_LEVEL_WARNING |
201 : : G_LOG_LEVEL_CRITICAL);
202 : :
203 : 1 : g_test_init (&argc, &argv, NULL);
204 : :
205 : 1 : g_test_add_func ("/gobject/static-iface", test_static_iface);
206 : 1 : g_test_add_func ("/gobject/dynamic-iface", test_dynamic_iface);
207 : :
208 : 1 : return g_test_run ();
209 : : }
|