1 # -*- Mode: Python; py-indent-offset: 4 -*-
2 # vim: tabstop=4 shiftwidth=4 expandtab
4 # Copyright (C) 2013 Simon Feltman <sfeltman@gnome.org>
6 # test_repository.py: Test for the GIRepository module
8 # This library is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU Lesser General Public
10 # License as published by the Free Software Foundation; either
11 # version 2.1 of the License, or (at your option) any later version.
13 # This library is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 # Lesser General Public License for more details.
18 # You should have received a copy of the GNU Lesser General Public
19 # License along with this library; if not, write to the Free Software
20 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
26 import gi._gi as GIRepository
27 from gi.module import repository as repo
28 from gi.repository import GObject
29 from gi.repository import GLib
30 from gi.repository import GIMarshallingTests
31 from gi.repository import GIRepository as IntrospectedRepository
41 def find_child_info(info, getter_name, name):
42 getter = getattr(info, getter_name)
43 for child in getter():
44 if child.get_name() == name:
47 raise ValueError('child info %s not found' % name)
50 class Test(unittest.TestCase):
52 repo.require('GObject')
53 repo.require('GIMarshallingTests')
55 def test_arg_info(self):
56 func_info = repo.find_by_name('GIMarshallingTests', 'array_fixed_out_struct')
57 args = func_info.get_arguments()
58 self.assertTrue(len(args), 1)
61 self.assertEqual(arg.get_container(), func_info)
62 self.assertEqual(arg.get_direction(), GIRepository.Direction.OUT)
63 self.assertEqual(arg.get_name(), 'structs')
64 self.assertEqual(arg.get_namespace(), 'GIMarshallingTests')
65 self.assertFalse(arg.is_caller_allocates())
66 self.assertFalse(arg.is_optional())
67 self.assertFalse(arg.is_return_value())
68 self.assertFalse(arg.may_be_null())
69 self.assertEqual(arg.get_destroy(), -1)
70 self.assertEqual(arg.get_ownership_transfer(), GIRepository.Transfer.NOTHING)
71 self.assertEqual(arg.get_scope(), GIRepository.ScopeType.INVALID)
72 self.assertEqual(arg.get_type().get_tag(), GIRepository.TypeTag.ARRAY)
74 def test_base_info(self):
75 info = repo.find_by_name('GIMarshallingTests', 'Object')
76 self.assertEqual(info.__name__, 'Object')
77 self.assertEqual(info.get_name(), 'Object')
78 self.assertEqual(info.__module__, 'gi.repository.GIMarshallingTests')
79 self.assertEqual(info.get_name_unescaped(), 'Object')
80 self.assertEqual(info.get_namespace(), 'GIMarshallingTests')
81 self.assertEqual(info.get_container(), None)
82 info2 = repo.find_by_name('GIMarshallingTests', 'Object')
83 self.assertFalse(info is info2)
84 self.assertEqual(info, info2)
85 self.assertTrue(info.equal(info2))
87 def test_object_info(self):
88 info = repo.find_by_name('GIMarshallingTests', 'Object')
89 self.assertEqual(info.get_parent(), repo.find_by_name('GObject', 'Object'))
90 self.assertTrue(isinstance(info.get_methods(), collections.Iterable))
91 self.assertTrue(isinstance(info.get_fields(), collections.Iterable))
92 self.assertTrue(isinstance(info.get_interfaces(), collections.Iterable))
93 self.assertTrue(isinstance(info.get_constants(), collections.Iterable))
94 self.assertTrue(isinstance(info.get_vfuncs(), collections.Iterable))
95 self.assertTrue(isinstance(info.get_properties(), collections.Iterable))
96 self.assertFalse(info.get_abstract())
97 self.assertEqual(info.get_class_struct(), repo.find_by_name('GIMarshallingTests', 'ObjectClass'))
98 self.assertEqual(info.get_type_name(), 'GIMarshallingTestsObject')
99 self.assertEqual(info.get_type_init(), 'gi_marshalling_tests_object_get_type')
100 self.assertFalse(info.get_fundamental())
101 self.assertEqual(info.get_parent(), repo.find_by_name('GObject', 'Object'))
103 def test_registered_type_info(self):
104 info = repo.find_by_name('GIMarshallingTests', 'Object')
105 # Call these from the class because GIObjectInfo overrides them
106 self.assertEqual(GIRepository.RegisteredTypeInfo.get_g_type(info),
107 GObject.type_from_name('GIMarshallingTestsObject'))
108 self.assertEqual(GIRepository.RegisteredTypeInfo.get_type_name(info),
109 'GIMarshallingTestsObject')
110 self.assertEqual(GIRepository.RegisteredTypeInfo.get_type_init(info),
111 'gi_marshalling_tests_object_get_type')
113 @unittest.skipUnless(has_cairo, 'Regress needs cairo')
114 def test_fundamental_object_info(self):
115 repo.require('Regress')
116 info = repo.find_by_name('Regress', 'TestFundamentalObject')
117 self.assertTrue(info.get_abstract())
118 self.assertTrue(info.get_fundamental())
119 self.assertEqual(info.get_ref_function(), 'regress_test_fundamental_object_ref')
120 self.assertEqual(info.get_unref_function(), 'regress_test_fundamental_object_unref')
121 self.assertEqual(info.get_get_value_function(), 'regress_test_value_get_fundamental_object')
122 self.assertEqual(info.get_set_value_function(), 'regress_test_value_set_fundamental_object')
124 def test_interface_info(self):
125 info = repo.find_by_name('GIMarshallingTests', 'Interface')
126 self.assertTrue(isinstance(info.get_methods(), collections.Iterable))
127 self.assertTrue(isinstance(info.get_vfuncs(), collections.Iterable))
128 self.assertTrue(isinstance(info.get_constants(), collections.Iterable))
129 self.assertTrue(isinstance(info.get_prerequisites(), collections.Iterable))
130 self.assertTrue(isinstance(info.get_properties(), collections.Iterable))
131 self.assertTrue(isinstance(info.get_signals(), collections.Iterable))
133 method = info.find_method('test_int8_in')
134 vfunc = info.find_vfunc('test_int8_in')
135 self.assertEqual(method.get_name(), 'test_int8_in')
136 self.assertEqual(vfunc.get_invoker(), method)
137 self.assertEqual(method.get_vfunc(), vfunc)
139 iface = info.get_iface_struct()
140 self.assertEqual(iface, repo.find_by_name('GIMarshallingTests', 'InterfaceIface'))
142 def test_struct_info(self):
143 info = repo.find_by_name('GIMarshallingTests', 'InterfaceIface')
144 self.assertTrue(isinstance(info, GIRepository.StructInfo))
145 self.assertTrue(isinstance(info.get_fields(), collections.Iterable))
146 self.assertTrue(isinstance(info.get_methods(), collections.Iterable))
147 self.assertTrue(isinstance(info.get_size(), int))
148 self.assertTrue(isinstance(info.get_alignment(), int))
149 self.assertTrue(info.is_gtype_struct())
150 self.assertFalse(info.is_foreign())
152 def test_enum_info(self):
153 info = repo.find_by_name('GIMarshallingTests', 'Enum')
154 self.assertTrue(isinstance(info, GIRepository.EnumInfo))
155 self.assertTrue(isinstance(info.get_values(), collections.Iterable))
156 self.assertTrue(isinstance(info.get_methods(), collections.Iterable))
157 self.assertFalse(info.is_flags())
158 self.assertTrue(info.get_storage_type() > 0) # might be platform dependent
160 def test_union_info(self):
161 info = repo.find_by_name('GIMarshallingTests', 'Union')
162 self.assertTrue(isinstance(info, GIRepository.UnionInfo))
163 self.assertTrue(isinstance(info.get_fields(), collections.Iterable))
164 self.assertTrue(isinstance(info.get_methods(), collections.Iterable))
166 def test_type_info(self):
167 func_info = repo.find_by_name('GIMarshallingTests', 'array_fixed_out_struct')
168 arg_info, = func_info.get_arguments()
169 type_info = arg_info.get_type()
171 self.assertTrue(type_info.is_pointer())
172 self.assertEqual(type_info.get_tag(), GIRepository.TypeTag.ARRAY)
173 self.assertEqual(type_info.get_tag_as_string(), 'array')
174 self.assertEqual(type_info.get_param_type(0).get_tag(),
175 GIRepository.TypeTag.INTERFACE)
176 self.assertEqual(type_info.get_param_type(0).get_interface(),
177 repo.find_by_name('GIMarshallingTests', 'SimpleStruct'))
178 self.assertEqual(type_info.get_interface(), None)
179 self.assertEqual(type_info.get_array_length(), -1)
180 self.assertEqual(type_info.get_array_fixed_size(), 2)
181 self.assertFalse(type_info.is_zero_terminated())
182 self.assertEqual(type_info.get_array_type(), GIRepository.ArrayType.C)
184 def test_field_info(self):
185 info = repo.find_by_name('GIMarshallingTests', 'InterfaceIface')
186 field = find_child_info(info, 'get_fields', 'test_int8_in')
187 self.assertEqual(field.get_name(), 'test_int8_in')
188 self.assertTrue(field.get_flags() & GIRepository.FieldInfoFlags.IS_READABLE)
189 self.assertFalse(field.get_flags() & GIRepository.FieldInfoFlags.IS_WRITABLE)
190 self.assertEqual(field.get_type().get_tag(), GIRepository.TypeTag.INTERFACE)
192 # don't test actual values because that might fail with architecture differences
193 self.assertTrue(isinstance(field.get_size(), int))
194 self.assertTrue(isinstance(field.get_offset(), int))
196 def test_property_info(self):
197 info = repo.find_by_name('GIMarshallingTests', 'PropertiesObject')
198 prop = find_child_info(info, 'get_properties', 'some-object')
200 flags = GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE | GObject.ParamFlags.CONSTRUCT
201 self.assertEqual(prop.get_flags(), flags)
202 self.assertEqual(prop.get_type().get_tag(), GIRepository.TypeTag.INTERFACE)
203 self.assertEqual(prop.get_type().get_interface(),
204 repo.find_by_name('GObject', 'Object'))
205 self.assertEqual(prop.get_ownership_transfer(), GIRepository.Transfer.NOTHING)
207 def test_callable_info(self):
208 func_info = repo.find_by_name('GIMarshallingTests', 'array_fixed_out_struct')
209 self.assertTrue(hasattr(func_info, 'invoke'))
210 self.assertTrue(isinstance(func_info.get_arguments(), collections.Iterable))
211 self.assertEqual(func_info.get_caller_owns(), GIRepository.Transfer.NOTHING)
212 self.assertFalse(func_info.may_return_null())
213 self.assertEqual(func_info.get_return_type().get_tag(), GIRepository.TypeTag.VOID)
214 self.assertRaises(AttributeError, func_info.get_return_attribute, '_not_an_attr')
216 @unittest.skip('https://bugzilla.gnome.org/show_bug.cgi?id=709462')
217 @unittest.skipUnless(has_cairo, 'Regress needs cairo')
218 def test_signal_info(self):
219 repo.require('Regress')
220 info = repo.find_by_name('Regress', 'TestObj')
221 sig_info = find_child_info(info, 'get_signals', 'test')
223 sig_flags = GObject.SignalFlags.RUN_LAST | \
224 GObject.SignalFlags.NO_RECURSE | GObject.SignalFlags.NO_HOOKS
226 self.assertTrue(sig_info is not None)
227 self.assertTrue(isinstance(sig_info, GIRepository.CallableInfo))
228 self.assertTrue(isinstance(sig_info, GIRepository.SignalInfo))
229 self.assertEqual(sig_info.get_name(), 'test')
230 self.assertEqual(sig_info.get_class_closure(), None)
231 self.assertFalse(sig_info.true_stops_emit())
232 self.assertEqual(sig_info.get_flags(), sig_flags)
234 @unittest.skip('https://bugzilla.gnome.org/show_bug.cgi?id=709462')
235 @unittest.skipUnless(has_cairo, 'Regress needs cairo')
236 def test_notify_signal_info_with_obj(self):
237 repo.require('Regress')
238 info = repo.find_by_name('Regress', 'TestObj')
239 sig_info = find_child_info(info, 'get_signals', 'sig-with-array-prop')
241 sig_flags = GObject.SignalFlags.RUN_LAST
243 self.assertTrue(sig_info is not None)
244 self.assertTrue(isinstance(sig_info, GIRepository.CallableInfo))
245 self.assertTrue(isinstance(sig_info, GIRepository.SignalInfo))
246 self.assertEqual(sig_info.get_name(), 'sig-with-array-prop')
247 self.assertEqual(sig_info.get_class_closure(), None)
248 self.assertFalse(sig_info.true_stops_emit())
249 self.assertEqual(sig_info.get_flags(), sig_flags)
251 def test_object_constructor(self):
252 info = repo.find_by_name('GIMarshallingTests', 'Object')
253 method = find_child_info(info, 'get_methods', 'new')
255 self.assertTrue(isinstance(method, GIRepository.CallableInfo))
256 self.assertTrue(isinstance(method, GIRepository.FunctionInfo))
257 self.assertTrue(method in info.get_methods())
258 self.assertEqual(method.get_name(), 'new')
259 self.assertFalse(method.is_method())
260 self.assertTrue(method.is_constructor())
261 self.assertEqual(method.get_symbol(), 'gi_marshalling_tests_object_new')
263 flags = method.get_flags()
264 self.assertFalse(flags & GIRepository.FunctionInfoFlags.IS_METHOD)
265 self.assertTrue(flags & GIRepository.FunctionInfoFlags.IS_CONSTRUCTOR)
266 self.assertFalse(flags & GIRepository.FunctionInfoFlags.IS_GETTER)
267 self.assertFalse(flags & GIRepository.FunctionInfoFlags.IS_SETTER)
268 self.assertFalse(flags & GIRepository.FunctionInfoFlags.WRAPS_VFUNC)
269 self.assertFalse(flags & GIRepository.FunctionInfoFlags.THROWS)
271 def test_method_info(self):
272 info = repo.find_by_name('GIMarshallingTests', 'Object')
273 method = find_child_info(info, 'get_methods', 'vfunc_return_value_only')
275 self.assertTrue(isinstance(method, GIRepository.CallableInfo))
276 self.assertTrue(isinstance(method, GIRepository.FunctionInfo))
277 self.assertTrue(method in info.get_methods())
278 self.assertEqual(method.get_name(), 'vfunc_return_value_only')
279 self.assertFalse(method.is_constructor())
280 self.assertEqual(method.get_symbol(), 'gi_marshalling_tests_object_vfunc_return_value_only')
281 self.assertTrue(method.is_method())
283 flags = method.get_flags()
284 self.assertTrue(flags & GIRepository.FunctionInfoFlags.IS_METHOD)
285 self.assertFalse(flags & GIRepository.FunctionInfoFlags.IS_CONSTRUCTOR)
286 self.assertFalse(flags & GIRepository.FunctionInfoFlags.IS_GETTER)
287 self.assertFalse(flags & GIRepository.FunctionInfoFlags.IS_SETTER)
288 self.assertFalse(flags & GIRepository.FunctionInfoFlags.WRAPS_VFUNC)
289 self.assertFalse(flags & GIRepository.FunctionInfoFlags.THROWS)
291 def test_vfunc_info(self):
292 info = repo.find_by_name('GIMarshallingTests', 'Object')
293 invoker = find_child_info(info, 'get_methods', 'vfunc_return_value_only')
294 vfunc = find_child_info(info, 'get_vfuncs', 'vfunc_return_value_only')
296 self.assertTrue(isinstance(vfunc, GIRepository.CallableInfo))
297 self.assertTrue(isinstance(vfunc, GIRepository.VFuncInfo))
298 self.assertEqual(vfunc.get_name(), 'vfunc_return_value_only')
299 self.assertEqual(vfunc.get_invoker(), invoker)
300 self.assertEqual(invoker, info.find_method('vfunc_return_value_only'))
301 self.assertEqual(vfunc.get_flags(), 0)
302 self.assertEqual(vfunc.get_offset(), 0xFFFF) # unknown offset
303 self.assertEqual(vfunc.get_signal(), None)
305 def test_flags_double_registration_error(self):
306 # a warning is printed for double registration and pygobject will
307 # also raise a RuntimeError.
308 GIMarshallingTests.NoTypeFlags # cause flags registration
309 info = repo.find_by_name('GIMarshallingTests', 'NoTypeFlags')
310 old_mask = GLib.log_set_always_fatal(GLib.LogLevelFlags.LEVEL_ERROR)
312 self.assertRaises(RuntimeError,
313 GIRepository.flags_register_new_gtype_and_add,
316 GLib.log_set_always_fatal(old_mask)
318 def test_enum_double_registration_error(self):
319 # a warning is printed for double registration and pygobject will
320 # also raise a RuntimeError.
321 GIMarshallingTests.Enum # cause enum registration
322 info = repo.find_by_name('GIMarshallingTests', 'Enum')
323 old_mask = GLib.log_set_always_fatal(GLib.LogLevelFlags.LEVEL_ERROR)
325 self.assertRaises(RuntimeError,
326 GIRepository.enum_register_new_gtype_and_add,
329 GLib.log_set_always_fatal(old_mask)
331 def test_enums(self):
332 self.assertTrue(hasattr(GIRepository, 'Direction'))
333 self.assertTrue(hasattr(GIRepository, 'Transfer'))
334 self.assertTrue(hasattr(GIRepository, 'ArrayType'))
335 self.assertTrue(hasattr(GIRepository, 'ScopeType'))
336 self.assertTrue(hasattr(GIRepository, 'VFuncInfoFlags'))
337 self.assertTrue(hasattr(GIRepository, 'FieldInfoFlags'))
338 self.assertTrue(hasattr(GIRepository, 'FunctionInfoFlags'))
339 self.assertTrue(hasattr(GIRepository, 'TypeTag'))
340 self.assertTrue(hasattr(GIRepository, 'InfoType'))
342 def test_introspected_argument_info(self):
343 self.assertTrue(isinstance(IntrospectedRepository.Argument.__info__,
344 GIRepository.UnionInfo))
346 arg = IntrospectedRepository.Argument()
347 self.assertTrue(isinstance(arg.__info__, GIRepository.UnionInfo))
349 old_info = IntrospectedRepository.Argument.__info__
350 IntrospectedRepository.Argument.__info__ = 'not an info'
351 self.assertRaises(TypeError, IntrospectedRepository.Argument)
352 IntrospectedRepository.Argument.__info__ = old_info
355 if __name__ == '__main__':