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 GIMarshallingTests
30 from gi.repository import GIRepository as IntrospectedRepository
32 from helper import capture_glib_warnings
35 def find_child_info(info, getter_name, name):
36 getter = getattr(info, getter_name)
37 for child in getter():
38 if child.get_name() == name:
41 raise ValueError('child info %s not found' % name)
44 class Test(unittest.TestCase):
47 repo.require('GObject')
48 repo.require('GIMarshallingTests')
50 def test_repo_get_dependencies(self):
51 self.assertRaises(TypeError, repo.get_dependencies)
52 self.assertEqual(repo.get_dependencies("GLib"), [])
53 self.assertEqual(repo.get_dependencies("GObject"), ["GLib-2.0"])
55 def test_repo_is_registered(self):
56 self.assertRaises(TypeError, repo.is_registered)
57 self.assertRaises(TypeError, repo.is_registered, None)
58 self.assertTrue(repo.is_registered("GIRepository"))
59 self.assertTrue(repo.is_registered("GIRepository", None))
60 self.assertTrue(isinstance(repo.is_registered("GIRepository"), bool))
61 self.assertTrue(repo.is_registered("GIRepository", "2.0"))
62 self.assertFalse(repo.is_registered("GIRepository", ""))
63 self.assertFalse(repo.is_registered("GIRepository", "99.0"))
64 self.assertFalse(repo.is_registered("GIRepository", "1.0"))
66 def test_repo_get_immediate_dependencies(self):
67 self.assertRaises(TypeError, repo.get_immediate_dependencies)
68 self.assertEqual(repo.get_immediate_dependencies("GLib"), [])
70 repo.get_immediate_dependencies("GObject"), ["GLib-2.0"])
72 repo.get_immediate_dependencies(namespace="GObject"), ["GLib-2.0"])
74 repo.get_immediate_dependencies("GIMarshallingTests"), ["Gio-2.0"])
76 def test_arg_info(self):
77 func_info = repo.find_by_name('GIMarshallingTests', 'array_fixed_out_struct')
78 args = func_info.get_arguments()
79 self.assertTrue(len(args), 1)
82 self.assertEqual(arg.get_container(), func_info)
83 self.assertEqual(arg.get_direction(), GIRepository.Direction.OUT)
84 self.assertEqual(arg.get_name(), 'structs')
85 self.assertEqual(arg.get_namespace(), 'GIMarshallingTests')
86 self.assertFalse(arg.is_caller_allocates())
87 self.assertFalse(arg.is_optional())
88 self.assertFalse(arg.is_return_value())
89 self.assertFalse(arg.may_be_null())
90 self.assertEqual(arg.get_destroy(), -1)
91 self.assertEqual(arg.get_ownership_transfer(), GIRepository.Transfer.NOTHING)
92 self.assertEqual(arg.get_scope(), GIRepository.ScopeType.INVALID)
93 self.assertEqual(arg.get_type().get_tag(), GIRepository.TypeTag.ARRAY)
95 def test_base_info(self):
96 info = repo.find_by_name('GIMarshallingTests', 'Object')
97 self.assertEqual(info.__name__, 'Object')
98 self.assertEqual(info.get_name(), 'Object')
99 self.assertEqual(info.__module__, 'gi.repository.GIMarshallingTests')
100 self.assertEqual(info.get_name_unescaped(), 'Object')
101 self.assertEqual(info.get_namespace(), 'GIMarshallingTests')
102 self.assertEqual(info.get_container(), None)
103 info2 = repo.find_by_name('GIMarshallingTests', 'Object')
104 self.assertFalse(info is info2)
105 self.assertEqual(info, info2)
106 self.assertTrue(info.equal(info2))
108 def test_object_info(self):
109 info = repo.find_by_name('GIMarshallingTests', 'Object')
110 self.assertEqual(info.get_parent(), repo.find_by_name('GObject', 'Object'))
111 self.assertTrue(isinstance(info.get_methods(), collections.Iterable))
112 self.assertTrue(isinstance(info.get_fields(), collections.Iterable))
113 self.assertTrue(isinstance(info.get_interfaces(), collections.Iterable))
114 self.assertTrue(isinstance(info.get_constants(), collections.Iterable))
115 self.assertTrue(isinstance(info.get_vfuncs(), collections.Iterable))
116 self.assertTrue(isinstance(info.get_properties(), collections.Iterable))
117 self.assertFalse(info.get_abstract())
118 self.assertEqual(info.get_class_struct(), repo.find_by_name('GIMarshallingTests', 'ObjectClass'))
119 self.assertEqual(info.get_type_name(), 'GIMarshallingTestsObject')
120 self.assertEqual(info.get_type_init(), 'gi_marshalling_tests_object_get_type')
121 self.assertFalse(info.get_fundamental())
122 self.assertEqual(info.get_parent(), repo.find_by_name('GObject', 'Object'))
124 def test_callable_inheritance(self):
125 self.assertTrue(issubclass(GIRepository.CallableInfo, GIRepository.BaseInfo))
126 self.assertTrue(issubclass(GIRepository.CallbackInfo, GIRepository.CallableInfo))
127 self.assertTrue(issubclass(GIRepository.FunctionInfo, GIRepository.CallableInfo))
128 self.assertTrue(issubclass(GIRepository.VFuncInfo, GIRepository.CallableInfo))
129 self.assertTrue(issubclass(GIRepository.SignalInfo, GIRepository.CallableInfo))
131 def test_registered_type_info(self):
132 info = repo.find_by_name('GIMarshallingTests', 'Object')
133 # Call these from the class because GIObjectInfo overrides them
134 self.assertEqual(GIRepository.RegisteredTypeInfo.get_g_type(info),
135 GObject.type_from_name('GIMarshallingTestsObject'))
136 self.assertEqual(GIRepository.RegisteredTypeInfo.get_type_name(info),
137 'GIMarshallingTestsObject')
138 self.assertEqual(GIRepository.RegisteredTypeInfo.get_type_init(info),
139 'gi_marshalling_tests_object_get_type')
141 def test_fundamental_object_info(self):
142 repo.require('Regress')
143 info = repo.find_by_name('Regress', 'TestFundamentalObject')
144 self.assertTrue(info.get_abstract())
145 self.assertTrue(info.get_fundamental())
146 self.assertEqual(info.get_ref_function(), 'regress_test_fundamental_object_ref')
147 self.assertEqual(info.get_unref_function(), 'regress_test_fundamental_object_unref')
148 self.assertEqual(info.get_get_value_function(), 'regress_test_value_get_fundamental_object')
149 self.assertEqual(info.get_set_value_function(), 'regress_test_value_set_fundamental_object')
151 def test_interface_info(self):
152 info = repo.find_by_name('GIMarshallingTests', 'Interface')
153 self.assertTrue(isinstance(info.get_methods(), collections.Iterable))
154 self.assertTrue(isinstance(info.get_vfuncs(), collections.Iterable))
155 self.assertTrue(isinstance(info.get_constants(), collections.Iterable))
156 self.assertTrue(isinstance(info.get_prerequisites(), collections.Iterable))
157 self.assertTrue(isinstance(info.get_properties(), collections.Iterable))
158 self.assertTrue(isinstance(info.get_signals(), collections.Iterable))
160 method = info.find_method('test_int8_in')
161 vfunc = info.find_vfunc('test_int8_in')
162 self.assertEqual(method.get_name(), 'test_int8_in')
163 self.assertEqual(vfunc.get_invoker(), method)
164 self.assertEqual(method.get_vfunc(), vfunc)
166 iface = info.get_iface_struct()
167 self.assertEqual(iface, repo.find_by_name('GIMarshallingTests', 'InterfaceIface'))
169 def test_struct_info(self):
170 info = repo.find_by_name('GIMarshallingTests', 'InterfaceIface')
171 self.assertTrue(isinstance(info, GIRepository.StructInfo))
172 self.assertTrue(isinstance(info.get_fields(), collections.Iterable))
173 self.assertTrue(isinstance(info.get_methods(), collections.Iterable))
174 self.assertTrue(isinstance(info.get_size(), int))
175 self.assertTrue(isinstance(info.get_alignment(), int))
176 self.assertTrue(info.is_gtype_struct())
177 self.assertFalse(info.is_foreign())
179 def test_enum_info(self):
180 info = repo.find_by_name('GIMarshallingTests', 'Enum')
181 self.assertTrue(isinstance(info, GIRepository.EnumInfo))
182 self.assertTrue(isinstance(info.get_values(), collections.Iterable))
183 self.assertTrue(isinstance(info.get_methods(), collections.Iterable))
184 self.assertFalse(info.is_flags())
185 self.assertTrue(info.get_storage_type() > 0) # might be platform dependent
187 def test_union_info(self):
188 info = repo.find_by_name('GIMarshallingTests', 'Union')
189 self.assertTrue(isinstance(info, GIRepository.UnionInfo))
190 self.assertTrue(isinstance(info.get_fields(), collections.Iterable))
191 self.assertTrue(isinstance(info.get_methods(), collections.Iterable))
192 self.assertTrue(isinstance(info.get_size(), int))
194 def test_type_info(self):
195 func_info = repo.find_by_name('GIMarshallingTests', 'array_fixed_out_struct')
196 arg_info, = func_info.get_arguments()
197 type_info = arg_info.get_type()
199 self.assertTrue(type_info.is_pointer())
200 self.assertEqual(type_info.get_tag(), GIRepository.TypeTag.ARRAY)
201 self.assertEqual(type_info.get_tag_as_string(), 'array')
202 self.assertEqual(type_info.get_param_type(0).get_tag(),
203 GIRepository.TypeTag.INTERFACE)
204 self.assertEqual(type_info.get_param_type(0).get_interface(),
205 repo.find_by_name('GIMarshallingTests', 'SimpleStruct'))
206 self.assertEqual(type_info.get_interface(), None)
207 self.assertEqual(type_info.get_array_length(), -1)
208 self.assertEqual(type_info.get_array_fixed_size(), 2)
209 self.assertFalse(type_info.is_zero_terminated())
210 self.assertEqual(type_info.get_array_type(), GIRepository.ArrayType.C)
212 def test_field_info(self):
213 info = repo.find_by_name('GIMarshallingTests', 'InterfaceIface')
214 field = find_child_info(info, 'get_fields', 'test_int8_in')
215 self.assertEqual(field.get_name(), 'test_int8_in')
216 self.assertTrue(field.get_flags() & GIRepository.FieldInfoFlags.IS_READABLE)
217 self.assertFalse(field.get_flags() & GIRepository.FieldInfoFlags.IS_WRITABLE)
218 self.assertEqual(field.get_type().get_tag(), GIRepository.TypeTag.INTERFACE)
220 # don't test actual values because that might fail with architecture differences
221 self.assertTrue(isinstance(field.get_size(), int))
222 self.assertTrue(isinstance(field.get_offset(), int))
224 def test_property_info(self):
225 info = repo.find_by_name('GIMarshallingTests', 'PropertiesObject')
226 prop = find_child_info(info, 'get_properties', 'some-object')
228 flags = GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE | GObject.ParamFlags.CONSTRUCT
229 self.assertEqual(prop.get_flags(), flags)
230 self.assertEqual(prop.get_type().get_tag(), GIRepository.TypeTag.INTERFACE)
231 self.assertEqual(prop.get_type().get_interface(),
232 repo.find_by_name('GObject', 'Object'))
233 self.assertEqual(prop.get_ownership_transfer(), GIRepository.Transfer.NOTHING)
235 def test_callable_info(self):
236 func_info = repo.find_by_name('GIMarshallingTests', 'array_fixed_out_struct')
237 self.assertTrue(hasattr(func_info, 'invoke'))
238 self.assertTrue(isinstance(func_info.get_arguments(), collections.Iterable))
239 self.assertEqual(func_info.get_caller_owns(), GIRepository.Transfer.NOTHING)
240 self.assertFalse(func_info.may_return_null())
241 self.assertEqual(func_info.get_return_type().get_tag(), GIRepository.TypeTag.VOID)
242 self.assertRaises(AttributeError, func_info.get_return_attribute, '_not_an_attr')
244 def test_signal_info(self):
245 repo.require('Regress')
246 info = repo.find_by_name('Regress', 'TestObj')
247 sig_info = find_child_info(info, 'get_signals', 'test')
249 sig_flags = GObject.SignalFlags.RUN_LAST | \
250 GObject.SignalFlags.NO_RECURSE | GObject.SignalFlags.NO_HOOKS
252 self.assertTrue(sig_info is not None)
253 self.assertTrue(isinstance(sig_info, GIRepository.CallableInfo))
254 self.assertTrue(isinstance(sig_info, GIRepository.SignalInfo))
255 self.assertEqual(sig_info.get_name(), 'test')
256 self.assertEqual(sig_info.get_class_closure(), None)
257 self.assertFalse(sig_info.true_stops_emit())
258 self.assertEqual(sig_info.get_flags(), sig_flags)
260 def test_notify_signal_info_with_obj(self):
261 repo.require('Regress')
262 info = repo.find_by_name('Regress', 'TestObj')
263 sig_info = find_child_info(info, 'get_signals', 'sig-with-array-prop')
265 sig_flags = GObject.SignalFlags.RUN_LAST
267 self.assertTrue(sig_info is not None)
268 self.assertTrue(isinstance(sig_info, GIRepository.CallableInfo))
269 self.assertTrue(isinstance(sig_info, GIRepository.SignalInfo))
270 self.assertEqual(sig_info.get_name(), 'sig-with-array-prop')
271 self.assertEqual(sig_info.get_class_closure(), None)
272 self.assertFalse(sig_info.true_stops_emit())
273 self.assertEqual(sig_info.get_flags(), sig_flags)
275 def test_object_constructor(self):
276 info = repo.find_by_name('GIMarshallingTests', 'Object')
277 method = find_child_info(info, 'get_methods', 'new')
279 self.assertTrue(isinstance(method, GIRepository.CallableInfo))
280 self.assertTrue(isinstance(method, GIRepository.FunctionInfo))
281 self.assertTrue(method in info.get_methods())
282 self.assertEqual(method.get_name(), 'new')
283 self.assertFalse(method.is_method())
284 self.assertTrue(method.is_constructor())
285 self.assertEqual(method.get_symbol(), 'gi_marshalling_tests_object_new')
287 flags = method.get_flags()
288 self.assertFalse(flags & GIRepository.FunctionInfoFlags.IS_METHOD)
289 self.assertTrue(flags & GIRepository.FunctionInfoFlags.IS_CONSTRUCTOR)
290 self.assertFalse(flags & GIRepository.FunctionInfoFlags.IS_GETTER)
291 self.assertFalse(flags & GIRepository.FunctionInfoFlags.IS_SETTER)
292 self.assertFalse(flags & GIRepository.FunctionInfoFlags.WRAPS_VFUNC)
293 self.assertFalse(flags & GIRepository.FunctionInfoFlags.THROWS)
295 def test_method_info(self):
296 info = repo.find_by_name('GIMarshallingTests', 'Object')
297 method = find_child_info(info, 'get_methods', 'vfunc_return_value_only')
299 self.assertTrue(isinstance(method, GIRepository.CallableInfo))
300 self.assertTrue(isinstance(method, GIRepository.FunctionInfo))
301 self.assertTrue(method in info.get_methods())
302 self.assertEqual(method.get_name(), 'vfunc_return_value_only')
303 self.assertFalse(method.is_constructor())
304 self.assertEqual(method.get_symbol(), 'gi_marshalling_tests_object_vfunc_return_value_only')
305 self.assertTrue(method.is_method())
307 flags = method.get_flags()
308 self.assertTrue(flags & GIRepository.FunctionInfoFlags.IS_METHOD)
309 self.assertFalse(flags & GIRepository.FunctionInfoFlags.IS_CONSTRUCTOR)
310 self.assertFalse(flags & GIRepository.FunctionInfoFlags.IS_GETTER)
311 self.assertFalse(flags & GIRepository.FunctionInfoFlags.IS_SETTER)
312 self.assertFalse(flags & GIRepository.FunctionInfoFlags.WRAPS_VFUNC)
313 self.assertFalse(flags & GIRepository.FunctionInfoFlags.THROWS)
315 def test_vfunc_info(self):
316 info = repo.find_by_name('GIMarshallingTests', 'Object')
317 invoker = find_child_info(info, 'get_methods', 'vfunc_return_value_only')
318 vfunc = find_child_info(info, 'get_vfuncs', 'vfunc_return_value_only')
320 self.assertTrue(isinstance(vfunc, GIRepository.CallableInfo))
321 self.assertTrue(isinstance(vfunc, GIRepository.VFuncInfo))
322 self.assertEqual(vfunc.get_name(), 'vfunc_return_value_only')
323 self.assertEqual(vfunc.get_invoker(), invoker)
324 self.assertEqual(invoker, info.find_method('vfunc_return_value_only'))
325 self.assertEqual(vfunc.get_flags(), 0)
326 self.assertEqual(vfunc.get_offset(), 0xFFFF) # unknown offset
327 self.assertEqual(vfunc.get_signal(), None)
329 def test_callable_can_throw_gerror(self):
330 info = repo.find_by_name('GIMarshallingTests', 'Object')
331 invoker = find_child_info(info, 'get_methods', 'vfunc_meth_with_error')
332 vfunc = find_child_info(info, 'get_vfuncs', 'vfunc_meth_with_err')
334 self.assertTrue(invoker.can_throw_gerror())
335 self.assertTrue(vfunc.can_throw_gerror())
337 # Test that args do not include the GError**
338 self.assertEqual(len(invoker.get_arguments()), 1)
339 self.assertEqual(len(vfunc.get_arguments()), 1)
341 # Sanity check method that does not throw.
342 invoker_no_throws = find_child_info(info, 'get_methods', 'method_int8_in')
343 self.assertFalse(invoker_no_throws.can_throw_gerror())
345 def test_flags_double_registration_error(self):
346 # a warning is printed for double registration and pygobject will
347 # also raise a RuntimeError.
348 GIMarshallingTests.NoTypeFlags # cause flags registration
349 info = repo.find_by_name('GIMarshallingTests', 'NoTypeFlags')
350 with capture_glib_warnings(allow_warnings=True):
351 self.assertRaises(RuntimeError,
352 GIRepository.flags_register_new_gtype_and_add,
355 def test_enum_double_registration_error(self):
356 # a warning is printed for double registration and pygobject will
357 # also raise a RuntimeError.
358 GIMarshallingTests.Enum # cause enum registration
359 info = repo.find_by_name('GIMarshallingTests', 'Enum')
360 with capture_glib_warnings(allow_warnings=True):
361 self.assertRaises(RuntimeError,
362 GIRepository.enum_register_new_gtype_and_add,
365 def test_enums(self):
366 self.assertTrue(hasattr(GIRepository, 'Direction'))
367 self.assertTrue(hasattr(GIRepository, 'Transfer'))
368 self.assertTrue(hasattr(GIRepository, 'ArrayType'))
369 self.assertTrue(hasattr(GIRepository, 'ScopeType'))
370 self.assertTrue(hasattr(GIRepository, 'VFuncInfoFlags'))
371 self.assertTrue(hasattr(GIRepository, 'FieldInfoFlags'))
372 self.assertTrue(hasattr(GIRepository, 'FunctionInfoFlags'))
373 self.assertTrue(hasattr(GIRepository, 'TypeTag'))
374 self.assertTrue(hasattr(GIRepository, 'InfoType'))
376 def test_introspected_argument_info(self):
377 self.assertTrue(isinstance(IntrospectedRepository.Argument.__info__,
378 GIRepository.UnionInfo))
380 arg = IntrospectedRepository.Argument()
381 self.assertTrue(isinstance(arg.__info__, GIRepository.UnionInfo))
383 old_info = IntrospectedRepository.Argument.__info__
384 IntrospectedRepository.Argument.__info__ = 'not an info'
385 self.assertRaises(TypeError, IntrospectedRepository.Argument)
386 IntrospectedRepository.Argument.__info__ = old_info
389 if __name__ == '__main__':