1 # -*- Mode: Python; py-indent-offset: 4 -*-
3 # vim: tabstop=4 shiftwidth=4 expandtab
14 from gi.repository import Regress as Everything
19 from gi.repository import GObject
20 from gi.repository import GLib
21 from gi.repository import Gio
24 from gi.repository import Gtk
29 if sys.version_info < (3, 0):
30 UNICHAR = "\xe2\x99\xa5"
31 PY2_UNICODE_UNICHAR = unicode(UNICHAR, 'UTF-8')
36 class RawGList(ctypes.Structure):
37 _fields_ = [('data', ctypes.c_void_p),
38 ('next', ctypes.c_void_p),
39 ('prev', ctypes.c_void_p)]
42 def from_wrapped(cls, obj):
43 offset = sys.getsizeof(object()) # size of PyObject_HEAD
44 return ctypes.POINTER(cls).from_address(id(obj) + offset)
47 @unittest.skipUnless(has_cairo, 'built without cairo support')
48 class TestEverything(unittest.TestCase):
50 def test_cairo_context(self):
51 context = Everything.test_cairo_context_full_return()
52 self.assertTrue(isinstance(context, cairo.Context))
54 surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10)
55 context = cairo.Context(surface)
56 Everything.test_cairo_context_none_in(context)
58 def test_cairo_surface(self):
59 surface = Everything.test_cairo_surface_none_return()
60 self.assertTrue(isinstance(surface, cairo.ImageSurface))
61 self.assertTrue(isinstance(surface, cairo.Surface))
62 self.assertEqual(surface.get_format(), cairo.FORMAT_ARGB32)
63 self.assertEqual(surface.get_width(), 10)
64 self.assertEqual(surface.get_height(), 10)
66 surface = Everything.test_cairo_surface_full_return()
67 self.assertTrue(isinstance(surface, cairo.ImageSurface))
68 self.assertTrue(isinstance(surface, cairo.Surface))
69 self.assertEqual(surface.get_format(), cairo.FORMAT_ARGB32)
70 self.assertEqual(surface.get_width(), 10)
71 self.assertEqual(surface.get_height(), 10)
73 surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10)
74 Everything.test_cairo_surface_none_in(surface)
76 surface = Everything.test_cairo_surface_full_out()
77 self.assertTrue(isinstance(surface, cairo.ImageSurface))
78 self.assertTrue(isinstance(surface, cairo.Surface))
79 self.assertEqual(surface.get_format(), cairo.FORMAT_ARGB32)
80 self.assertEqual(surface.get_width(), 10)
81 self.assertEqual(surface.get_height(), 10)
84 self.assertEqual(Everything.test_boolean(False), False)
85 self.assertEqual(Everything.test_boolean(True), True)
86 self.assertEqual(Everything.test_boolean('hello'), True)
87 self.assertEqual(Everything.test_boolean(''), False)
89 self.assertEqual(Everything.test_boolean_true(True), True)
90 self.assertEqual(Everything.test_boolean_false(False), False)
93 self.assertEqual(Everything.test_int8(GObject.G_MAXINT8),
95 self.assertEqual(Everything.test_int8(GObject.G_MININT8),
97 self.assertRaises(ValueError, Everything.test_int8, GObject.G_MAXINT8 + 1)
99 self.assertEqual(Everything.test_uint8(GObject.G_MAXUINT8),
101 self.assertEqual(Everything.test_uint8(0), 0)
102 self.assertRaises(ValueError, Everything.test_uint8, -1)
103 self.assertRaises(ValueError, Everything.test_uint8, GObject.G_MAXUINT8 + 1)
105 def test_int16(self):
106 self.assertEqual(Everything.test_int16(GObject.G_MAXINT16),
108 self.assertEqual(Everything.test_int16(GObject.G_MININT16),
110 self.assertRaises(ValueError, Everything.test_int16, GObject.G_MAXINT16 + 1)
112 self.assertEqual(Everything.test_uint16(GObject.G_MAXUINT16),
114 self.assertEqual(Everything.test_uint16(0), 0)
115 self.assertRaises(ValueError, Everything.test_uint16, -1)
116 self.assertRaises(ValueError, Everything.test_uint16, GObject.G_MAXUINT16 + 1)
118 def test_int32(self):
119 self.assertEqual(Everything.test_int32(GObject.G_MAXINT32),
121 self.assertEqual(Everything.test_int32(GObject.G_MININT32),
123 self.assertRaises(ValueError, Everything.test_int32, GObject.G_MAXINT32 + 1)
125 self.assertEqual(Everything.test_uint32(GObject.G_MAXUINT32),
127 self.assertEqual(Everything.test_uint32(0), 0)
128 self.assertRaises(ValueError, Everything.test_uint32, -1)
129 self.assertRaises(ValueError, Everything.test_uint32, GObject.G_MAXUINT32 + 1)
131 def test_int64(self):
132 self.assertEqual(Everything.test_int64(GObject.G_MAXINT64),
134 self.assertEqual(Everything.test_int64(GObject.G_MININT64),
136 self.assertRaises(ValueError, Everything.test_int64, GObject.G_MAXINT64 + 1)
138 self.assertEqual(Everything.test_uint64(GObject.G_MAXUINT64),
140 self.assertEqual(Everything.test_uint64(0), 0)
141 self.assertRaises(ValueError, Everything.test_uint64, -1)
142 self.assertRaises(ValueError, Everything.test_uint64, GObject.G_MAXUINT64 + 1)
145 self.assertEqual(Everything.test_int(GObject.G_MAXINT),
147 self.assertEqual(Everything.test_int(GObject.G_MININT),
149 self.assertRaises(ValueError, Everything.test_int, GObject.G_MAXINT + 1)
151 self.assertEqual(Everything.test_uint(GObject.G_MAXUINT),
153 self.assertEqual(Everything.test_uint(0), 0)
154 self.assertRaises(ValueError, Everything.test_uint, -1)
155 self.assertRaises(ValueError, Everything.test_uint, GObject.G_MAXUINT + 1)
157 def test_short(self):
158 self.assertEqual(Everything.test_short(GObject.G_MAXSHORT),
160 self.assertEqual(Everything.test_short(GObject.G_MINSHORT),
162 self.assertRaises(ValueError, Everything.test_short, GObject.G_MAXSHORT + 1)
164 self.assertEqual(Everything.test_ushort(GObject.G_MAXUSHORT),
166 self.assertEqual(Everything.test_ushort(0), 0)
167 self.assertRaises(ValueError, Everything.test_ushort, -1)
168 self.assertRaises(ValueError, Everything.test_ushort, GObject.G_MAXUSHORT + 1)
171 self.assertEqual(Everything.test_long(GObject.G_MAXLONG),
173 self.assertEqual(Everything.test_long(GObject.G_MINLONG),
175 self.assertRaises(ValueError, Everything.test_long, GObject.G_MAXLONG + 1)
177 self.assertEqual(Everything.test_ulong(GObject.G_MAXULONG),
179 self.assertEqual(Everything.test_ulong(0), 0)
180 self.assertRaises(ValueError, Everything.test_ulong, -1)
181 self.assertRaises(ValueError, Everything.test_ulong, GObject.G_MAXULONG + 1)
184 self.assertEqual(Everything.test_ssize(GObject.G_MAXSSIZE),
186 self.assertEqual(Everything.test_ssize(GObject.G_MINSSIZE),
188 self.assertRaises(ValueError, Everything.test_ssize, GObject.G_MAXSSIZE + 1)
190 self.assertEqual(Everything.test_size(GObject.G_MAXSIZE),
192 self.assertEqual(Everything.test_size(0), 0)
193 self.assertRaises(ValueError, Everything.test_size, -1)
194 self.assertRaises(ValueError, Everything.test_size, GObject.G_MAXSIZE + 1)
196 def test_timet(self):
197 self.assertEqual(Everything.test_timet(42), 42)
198 self.assertRaises(ValueError, Everything.test_timet, GObject.G_MAXUINT64 + 1)
200 def test_unichar(self):
201 self.assertEqual("c", Everything.test_unichar("c"))
203 if sys.version_info < (3, 0):
204 self.assertEqual(UNICHAR, Everything.test_unichar(PY2_UNICODE_UNICHAR))
205 self.assertEqual(UNICHAR, Everything.test_unichar(UNICHAR))
206 self.assertRaises(TypeError, Everything.test_unichar, "")
207 self.assertRaises(TypeError, Everything.test_unichar, "morethanonechar")
209 def test_float(self):
210 self.assertEqual(Everything.test_float(GObject.G_MAXFLOAT),
212 self.assertEqual(Everything.test_float(GObject.G_MINFLOAT),
214 self.assertRaises(ValueError, Everything.test_float, GObject.G_MAXFLOAT * 2)
216 def test_double(self):
217 self.assertEqual(Everything.test_double(GObject.G_MAXDOUBLE),
219 self.assertEqual(Everything.test_double(GObject.G_MINDOUBLE),
221 self.assertRaises(ValueError, Everything.test_double, GObject.G_MAXDOUBLE * 2)
223 (two, three) = Everything.test_multi_double_args(2.5)
224 self.assertAlmostEqual(two, 5.0)
225 self.assertAlmostEqual(three, 7.5)
227 def test_value(self):
228 self.assertEqual(Everything.test_int_value_arg(GObject.G_MAXINT), GObject.G_MAXINT)
229 self.assertEqual(Everything.test_value_return(GObject.G_MAXINT), GObject.G_MAXINT)
231 def test_variant(self):
232 v = Everything.test_gvariant_i()
233 self.assertEqual(v.get_type_string(), 'i')
234 self.assertEqual(v.get_int32(), 1)
236 v = Everything.test_gvariant_s()
237 self.assertEqual(v.get_type_string(), 's')
238 self.assertEqual(v.get_string(), 'one')
240 v = Everything.test_gvariant_v()
241 self.assertEqual(v.get_type_string(), 'v')
243 self.assertEqual(vi.get_type_string(), 's')
244 self.assertEqual(vi.get_string(), 'contents')
246 v = Everything.test_gvariant_as()
247 self.assertEqual(v.get_type_string(), 'as')
248 self.assertEqual(v.get_strv(), ['one', 'two', 'three'])
250 v = Everything.test_gvariant_asv()
251 self.assertEqual(v.get_type_string(), 'a{sv}')
252 self.assertEqual(v.lookup_value('nosuchkey', None), None)
253 name = v.lookup_value('name', None)
254 self.assertEqual(name.get_string(), 'foo')
255 timeout = v.lookup_value('timeout', None)
256 self.assertEqual(timeout.get_int32(), 10)
258 def test_string(self):
259 const_str = b'const \xe2\x99\xa5 utf8'
260 if sys.version_info >= (3, 0):
261 const_str = const_str.decode('UTF-8')
262 noconst_str = 'non' + const_str
264 self.assertEqual(Everything.test_utf8_const_return(), const_str)
265 self.assertEqual(Everything.test_utf8_nonconst_return(), noconst_str)
266 self.assertEqual(Everything.test_utf8_out(), noconst_str)
268 Everything.test_utf8_const_in(const_str)
269 self.assertEqual(Everything.test_utf8_inout(const_str), noconst_str)
271 self.assertEqual(Everything.test_filename_return(), ['åäö', '/etc/fstab'])
273 # returns g_utf8_strlen() in out argument
274 self.assertEqual(Everything.test_int_out_utf8(''), 0)
275 self.assertEqual(Everything.test_int_out_utf8('hello world'), 11)
276 self.assertEqual(Everything.test_int_out_utf8('åäö'), 3)
278 self.assertEqual(Everything.test_utf8_out_out(), ('first', 'second'))
279 self.assertEqual(Everything.test_utf8_out_nonconst_return(), ('first', 'second'))
282 self.assertEqual(Everything.test_enum_param(Everything.TestEnum.VALUE1), 'value1')
283 self.assertEqual(Everything.test_enum_param(Everything.TestEnum.VALUE3), 'value3')
284 self.assertRaises(TypeError, Everything.test_enum_param, 'hello')
286 # FIXME: ValueError: invalid enum value: 2147483648
287 @unittest.expectedFailure
288 def test_enum_unsigned(self):
289 self.assertEqual(Everything.test_unsigned_enum_param(Everything.TestEnumUnsigned.VALUE1), 'value1')
290 self.assertEqual(Everything.test_unsigned_enum_param(Everything.TestEnumUnsigned.VALUE3), 'value3')
291 self.assertRaises(TypeError, Everything.test_unsigned_enum_param, 'hello')
293 def test_flags(self):
294 result = Everything.global_get_flags_out()
295 # assert that it's not an int
296 self.assertEqual(type(result), Everything.TestFlags)
297 self.assertEqual(result, Everything.TestFlags.FLAG1 | Everything.TestFlags.FLAG3)
299 def test_floating(self):
300 e = Everything.TestFloating()
301 self.assertEqual(e.__grefcount__, 1)
303 e = GObject.new(Everything.TestFloating)
304 self.assertEqual(e.__grefcount__, 1)
306 e = Everything.TestFloating.new()
307 self.assertEqual(e.__grefcount__, 1)
309 def test_caller_allocates(self):
310 struct_a = Everything.TestStructA()
311 struct_a.some_int = 10
312 struct_a.some_int8 = 21
313 struct_a.some_double = 3.14
314 struct_a.some_enum = Everything.TestEnum.VALUE3
316 struct_a_clone = struct_a.clone()
317 self.assertTrue(struct_a != struct_a_clone)
318 self.assertEqual(struct_a.some_int, struct_a_clone.some_int)
319 self.assertEqual(struct_a.some_int8, struct_a_clone.some_int8)
320 self.assertEqual(struct_a.some_double, struct_a_clone.some_double)
321 self.assertEqual(struct_a.some_enum, struct_a_clone.some_enum)
323 struct_b = Everything.TestStructB()
324 struct_b.some_int8 = 8
325 struct_b.nested_a.some_int = 20
326 struct_b.nested_a.some_int8 = 12
327 struct_b.nested_a.some_double = 333.3333
328 struct_b.nested_a.some_enum = Everything.TestEnum.VALUE2
330 struct_b_clone = struct_b.clone()
331 self.assertTrue(struct_b != struct_b_clone)
332 self.assertEqual(struct_b.some_int8, struct_b_clone.some_int8)
333 self.assertEqual(struct_b.nested_a.some_int, struct_b_clone.nested_a.some_int)
334 self.assertEqual(struct_b.nested_a.some_int8, struct_b_clone.nested_a.some_int8)
335 self.assertEqual(struct_b.nested_a.some_double, struct_b_clone.nested_a.some_double)
336 self.assertEqual(struct_b.nested_a.some_enum, struct_b_clone.nested_a.some_enum)
338 struct_a = Everything.test_struct_a_parse('ignored')
339 self.assertEqual(struct_a.some_int, 23)
341 def test_wrong_type_of_arguments(self):
343 Everything.test_int8()
345 (e_type, e) = sys.exc_info()[:2]
346 self.assertEqual(e.args, ("test_int8() takes exactly 1 argument (0 given)",))
348 def test_gtypes(self):
349 gchararray_gtype = GObject.type_from_name('gchararray')
350 gtype = Everything.test_gtype(str)
351 self.assertEqual(gchararray_gtype, gtype)
352 gtype = Everything.test_gtype('gchararray')
353 self.assertEqual(gchararray_gtype, gtype)
354 gobject_gtype = GObject.GObject.__gtype__
355 gtype = Everything.test_gtype(GObject.GObject)
356 self.assertEqual(gobject_gtype, gtype)
357 gtype = Everything.test_gtype('GObject')
358 self.assertEqual(gobject_gtype, gtype)
359 self.assertRaises(TypeError, Everything.test_gtype, 'invalidgtype')
361 class NotARegisteredClass(object):
364 self.assertRaises(TypeError, Everything.test_gtype, NotARegisteredClass)
366 class ARegisteredClass(GObject.GObject):
367 __gtype_name__ = 'EverythingTestsARegisteredClass'
369 gtype = Everything.test_gtype('EverythingTestsARegisteredClass')
370 self.assertEqual(ARegisteredClass.__gtype__, gtype)
371 gtype = Everything.test_gtype(ARegisteredClass)
372 self.assertEqual(ARegisteredClass.__gtype__, gtype)
373 self.assertRaises(TypeError, Everything.test_gtype, 'ARegisteredClass')
376 attr_list = dir(Everything)
378 # test that typelib attributes are listed
379 self.assertTrue('TestStructA' in attr_list)
381 # test that class attributes and methods are listed
382 self.assertTrue('__class__' in attr_list)
383 self.assertTrue('__dir__' in attr_list)
384 self.assertTrue('__repr__' in attr_list)
386 # test that instance members are listed
387 self.assertTrue('_namespace' in attr_list)
388 self.assertTrue('_version' in attr_list)
390 # test that there are no duplicates returned
391 self.assertEqual(len(attr_list), len(set(attr_list)))
393 def test_array(self):
394 self.assertEqual(Everything.test_array_int_in([]), 0)
395 self.assertEqual(Everything.test_array_int_in([1, 5, -2]), 4)
396 self.assertEqual(Everything.test_array_int_out(), [0, 1, 2, 3, 4])
397 self.assertEqual(Everything.test_array_int_full_out(), [0, 1, 2, 3, 4])
398 self.assertEqual(Everything.test_array_int_none_out(), [1, 2, 3, 4, 5])
399 self.assertEqual(Everything.test_array_int_inout([1, 5, 42, -8]), [6, 43, -7])
401 if sys.version_info >= (3, 0):
402 self.assertEqual(Everything.test_array_gint8_in(b'\x01\x03\x05'), 9)
403 self.assertEqual(Everything.test_array_gint8_in([1, 3, 5, -50]), -41)
404 self.assertEqual(Everything.test_array_gint16_in([256, 257, -1000, 10000]), 9513)
405 self.assertEqual(Everything.test_array_gint32_in([30000, 1, -2]), 29999)
406 self.assertEqual(Everything.test_array_gint64_in([2 ** 33, 2 ** 34]), 2 ** 33 + 2 ** 34)
408 self.assertEqual(Everything.test_array_gtype_in(
409 [GObject.TYPE_STRING, GObject.TYPE_UINT64, GObject.TYPE_VARIANT]),
410 '[gchararray,guint64,GVariant,]')
412 def test_array_fixed_size(self):
414 self.assertEqual(Everything.test_array_fixed_size_int_in([1, 2, -10, 5, 3]), 1)
415 self.assertRaises(ValueError, Everything.test_array_fixed_size_int_in, [1, 2, 3, 4])
416 self.assertRaises(ValueError, Everything.test_array_fixed_size_int_in, [1, 2, 3, 4, 5, 6])
418 self.assertEqual(Everything.test_array_fixed_size_int_out(), [0, 1, 2, 3, 4])
419 self.assertEqual(Everything.test_array_fixed_size_int_return(), [0, 1, 2, 3, 4])
421 def test_ptrarray(self):
423 result = Everything.test_garray_container_return()
424 self.assertEqual(result, ['regress'])
428 result = Everything.test_garray_full_return()
429 self.assertEqual(result, ['regress'])
433 self.assertEqual(Everything.test_strv_out(), ['thanks', 'for', 'all', 'the', 'fish'])
434 self.assertEqual(Everything.test_strv_out_c(), ['thanks', 'for', 'all', 'the', 'fish'])
435 self.assertEqual(Everything.test_strv_out_container(), ['1', '2', '3'])
436 self.assertEqual(Everything.test_strv_outarg(), ['1', '2', '3'])
438 self.assertEqual(Everything.test_strv_in_gvalue(), ['one', 'two', 'three'])
440 Everything.test_strv_in(['1', '2', '3'])
442 def test_glist(self):
443 self.assertEqual(Everything.test_glist_nothing_return(), ['1', '2', '3'])
444 self.assertEqual(Everything.test_glist_nothing_return2(), ['1', '2', '3'])
445 self.assertEqual(Everything.test_glist_container_return(), ['1', '2', '3'])
446 self.assertEqual(Everything.test_glist_everything_return(), ['1', '2', '3'])
448 Everything.test_glist_nothing_in(['1', '2', '3'])
449 Everything.test_glist_nothing_in2(['1', '2', '3'])
451 def test_gslist(self):
452 self.assertEqual(Everything.test_gslist_nothing_return(), ['1', '2', '3'])
453 self.assertEqual(Everything.test_gslist_nothing_return2(), ['1', '2', '3'])
454 self.assertEqual(Everything.test_gslist_container_return(), ['1', '2', '3'])
455 self.assertEqual(Everything.test_gslist_everything_return(), ['1', '2', '3'])
457 Everything.test_gslist_nothing_in(['1', '2', '3'])
458 Everything.test_gslist_nothing_in2(['1', '2', '3'])
460 def test_hash_return(self):
461 expected = {'foo': 'bar', 'baz': 'bat', 'qux': 'quux'}
463 self.assertEqual(Everything.test_ghash_null_return(), None)
464 self.assertEqual(Everything.test_ghash_nothing_return(), expected)
465 self.assertEqual(Everything.test_ghash_nothing_return(), expected)
466 self.assertEqual(Everything.test_ghash_container_return(), expected)
467 self.assertEqual(Everything.test_ghash_everything_return(), expected)
469 result = Everything.test_ghash_gvalue_return()
470 self.assertEqual(result['integer'], 12)
471 self.assertEqual(result['boolean'], True)
472 self.assertEqual(result['string'], 'some text')
473 self.assertEqual(result['strings'], ['first', 'second', 'third'])
474 self.assertEqual(result['flags'], Everything.TestFlags.FLAG1 | Everything.TestFlags.FLAG3)
475 self.assertEqual(result['enum'], Everything.TestEnum.VALUE2)
478 # FIXME: CRITICAL **: Unsupported type ghash
479 def disabled_test_hash_return_nested(self):
480 self.assertEqual(Everything.test_ghash_nested_everything_return(), {})
481 self.assertEqual(Everything.test_ghash_nested_everything_return2(), {})
483 def test_hash_in(self):
484 # specifying a simple string array for "strings" does not work due to
485 # https://bugzilla.gnome.org/show_bug.cgi?id=666636
486 # workaround by explicitly building a GStrv object
488 __gtype__ = GObject.TYPE_STRV
490 expected = {'foo': 'bar', 'baz': 'bat', 'qux': 'quux'}
492 Everything.test_ghash_nothing_in(expected)
493 Everything.test_ghash_nothing_in2(expected)
495 data = {'integer': 12,
497 'string': 'some text',
498 'strings': GStrv(['first', 'second', 'third']),
499 'flags': Everything.TestFlags.FLAG1 | Everything.TestFlags.FLAG3,
500 'enum': Everything.TestEnum.VALUE2,
502 Everything.test_ghash_gvalue_in(data)
505 def test_struct_gpointer(self):
507 raw = RawGList.from_wrapped(glist)
509 self.assertEqual(glist.data, None)
510 self.assertEqual(raw.contents.data, None)
513 self.assertEqual(glist.data, 123)
514 self.assertEqual(raw.contents.data, 123)
517 self.assertEqual(glist.data, None)
518 self.assertEqual(raw.contents.data, None)
520 # Setting to anything other than an int should raise
521 self.assertRaises(TypeError, setattr, glist.data, 'nan')
522 self.assertRaises(TypeError, setattr, glist.data, object())
523 self.assertRaises(TypeError, setattr, glist.data, 123.321)
525 def test_struct_opaque(self):
526 # we should get a sensible error message
528 Everything.TestBoxedPrivate()
529 self.fail('allocating disguised struct without default constructor unexpectedly succeeded')
531 (e_type, e_value, e_tb) = sys.exc_info()
532 self.assertEqual(e_type, TypeError)
533 self.assertTrue('TestBoxedPrivate' in str(e_value), str(e_value))
534 self.assertTrue('override' in str(e_value), str(e_value))
535 self.assertTrue('constructor' in str(e_value), str(e_value))
536 tb = ''.join(traceback.format_exception(e_type, e_value, e_tb))
537 self.assertTrue('tests/test_everything.py", line' in tb, tb)
540 @unittest.skipUnless(has_cairo, 'built without cairo support')
541 class TestNullableArgs(unittest.TestCase):
542 def test_in_nullable_hash(self):
543 Everything.test_ghash_null_in(None)
545 def test_in_nullable_list(self):
546 Everything.test_gslist_null_in(None)
547 Everything.test_glist_null_in(None)
548 Everything.test_gslist_null_in([])
549 Everything.test_glist_null_in([])
551 def test_in_nullable_array(self):
552 Everything.test_array_int_null_in(None)
553 Everything.test_array_int_null_in([])
555 def test_in_nullable_string(self):
556 Everything.test_utf8_null_in(None)
558 def test_in_nullable_object(self):
559 Everything.func_obj_null_in(None)
561 def test_out_nullable_hash(self):
562 self.assertEqual(None, Everything.test_ghash_null_out())
564 def test_out_nullable_list(self):
565 self.assertEqual([], Everything.test_gslist_null_out())
566 self.assertEqual([], Everything.test_glist_null_out())
568 def test_out_nullable_array(self):
569 self.assertEqual([], Everything.test_array_int_null_out())
571 def test_out_nullable_string(self):
572 self.assertEqual(None, Everything.test_utf8_null_out())
574 def test_out_nullable_object(self):
575 self.assertEqual(None, Everything.TestObj.null_out())
578 @unittest.skipUnless(has_cairo, 'built without cairo support')
579 class TestCallbacks(unittest.TestCase):
581 main_loop = GLib.MainLoop()
583 def test_callback(self):
584 TestCallbacks.called = False
587 TestCallbacks.called = True
589 Everything.test_simple_callback(callback)
590 self.assertTrue(TestCallbacks.called)
592 def test_callback_exception(self):
594 This test ensures that we get errors from callbacks correctly
595 and in particular that we do not segv when callbacks fail
599 self.fail('unexpected surviving zero divsion:' + str(x))
601 # note that we do NOT expect the ZeroDivisionError to be propagated
602 # through from the callback, as it crosses the Python<->C boundary
603 # twice. (See GNOME #616279)
604 Everything.test_simple_callback(callback)
606 def test_double_callback_exception(self):
608 This test ensures that we get errors from callbacks correctly
609 and in particular that we do not segv when callbacks fail
613 self.fail('unexpected surviving zero divsion:' + str(x))
616 Everything.test_boolean(True)
617 Everything.test_boolean(False)
618 Everything.test_simple_callback(badcallback())
620 # note that we do NOT expect the ZeroDivisionError to be propagated
621 # through from the callback, as it crosses the Python<->C boundary
622 # twice. (See GNOME #616279)
623 Everything.test_simple_callback(callback)
625 def test_return_value_callback(self):
626 TestCallbacks.called = False
629 TestCallbacks.called = True
632 self.assertEqual(Everything.test_callback(callback), 44)
633 self.assertTrue(TestCallbacks.called)
635 def test_callback_scope_async(self):
636 TestCallbacks.called = False
639 def callback(user_data):
640 self.assertEqual(user_data, ud)
641 TestCallbacks.called = True
644 ud_refcount = sys.getrefcount(ud)
645 callback_refcount = sys.getrefcount(callback)
647 self.assertEqual(Everything.test_callback_async(callback, ud), None)
648 # Callback should not have run and the ref count is increased by 1
649 self.assertEqual(TestCallbacks.called, False)
650 self.assertEqual(sys.getrefcount(callback), callback_refcount + 1)
651 self.assertEqual(sys.getrefcount(ud), ud_refcount + 1)
653 # test_callback_thaw_async will run the callback previously supplied.
654 # references should be auto decremented after this call.
655 self.assertEqual(Everything.test_callback_thaw_async(), 44)
656 self.assertTrue(TestCallbacks.called)
658 # Make sure refcounts are returned to normal
659 self.assertEqual(sys.getrefcount(callback), callback_refcount)
660 self.assertEqual(sys.getrefcount(ud), ud_refcount)
662 def test_callback_scope_call_multi(self):
663 # This tests a callback that gets called multiple times from a
664 # single scope call in python.
665 TestCallbacks.called = 0
668 TestCallbacks.called += 1
669 return TestCallbacks.called
671 refcount = sys.getrefcount(callback)
672 result = Everything.test_multi_callback(callback)
673 # first callback should give 1, second 2, and the function sums them up
674 self.assertEqual(result, 3)
675 self.assertEqual(TestCallbacks.called, 2)
676 self.assertEqual(sys.getrefcount(callback), refcount)
678 # FIXME: TypeError: callback() takes 2 positional arguments but 4 were given
679 # does not remove the array length arguments
680 @unittest.expectedFailure
681 def test_callback_scope_call_array(self):
682 # This tests a callback that gets called multiple times from a
683 # single scope call in python with array arguments
684 TestCallbacks.callargs = []
687 #def callback(one, one_length, two, two_length):
688 def callback(one, two):
689 TestCallbacks.callargs.append((one, two))
690 return len(TestCallbacks.callargs)
692 refcount = sys.getrefcount(callback)
693 result = Everything.test_array_callback(callback)
694 # first callback should give 1, second 2, and the function sums them up
695 self.assertEqual(result, 3)
696 self.assertEqual(TestCallbacks.callargs,
697 [([-1, 0, 1, 2], ['one', 'two', 'three'])] * 2)
698 self.assertEqual(sys.getrefcount(callback), refcount)
700 def test_callback_userdata(self):
701 TestCallbacks.called = 0
703 def callback(userdata):
704 self.assertEqual(userdata, "Test%d" % TestCallbacks.called)
705 TestCallbacks.called += 1
706 return TestCallbacks.called
709 val = Everything.test_callback_user_data(callback, "Test%d" % i)
710 self.assertEqual(val, i + 1)
712 self.assertEqual(TestCallbacks.called, 100)
714 def test_async_ready_callback(self):
715 TestCallbacks.called = False
716 TestCallbacks.main_loop = GLib.MainLoop()
718 def callback(obj, result, user_data):
719 TestCallbacks.main_loop.quit()
720 TestCallbacks.called = True
722 Everything.test_async_ready_callback(callback)
724 TestCallbacks.main_loop.run()
726 self.assertTrue(TestCallbacks.called)
728 def test_callback_scope_notified_with_destroy(self):
729 TestCallbacks.called = 0
730 ud = 'Test scope notified data 33'
732 def callback(user_data):
733 self.assertEqual(user_data, ud)
734 TestCallbacks.called += 1
737 value_refcount = sys.getrefcount(ud)
738 callback_refcount = sys.getrefcount(callback)
740 # Callback is immediately called.
742 res = Everything.test_callback_destroy_notify(callback, ud)
743 self.assertEqual(res, 33)
745 self.assertEqual(TestCallbacks.called, 100)
746 self.assertEqual(sys.getrefcount(callback), callback_refcount + 100)
747 self.assertEqual(sys.getrefcount(ud), value_refcount + 100)
749 # thaw will call the callback again, this time resources should be freed
750 self.assertEqual(Everything.test_callback_thaw_notifications(), 33 * 100)
751 self.assertEqual(TestCallbacks.called, 200)
752 self.assertEqual(sys.getrefcount(callback), callback_refcount)
753 self.assertEqual(sys.getrefcount(ud), value_refcount)
755 def test_callback_scope_notified_with_destroy_no_user_data(self):
756 TestCallbacks.called = 0
758 def callback(user_data):
759 self.assertEqual(user_data, None)
760 TestCallbacks.called += 1
763 callback_refcount = sys.getrefcount(callback)
765 # Run with warning as exception
766 with warnings.catch_warnings(record=True) as w:
767 warnings.simplefilter("error")
768 self.assertRaises(RuntimeWarning,
769 Everything.test_callback_destroy_notify_no_user_data,
772 self.assertEqual(TestCallbacks.called, 0)
773 self.assertEqual(sys.getrefcount(callback), callback_refcount)
775 # Run with warning as warning
776 with warnings.catch_warnings(record=True) as w:
777 # Cause all warnings to always be triggered.
778 warnings.simplefilter("default")
780 res = Everything.test_callback_destroy_notify_no_user_data(callback)
782 self.assertEqual(len(w), 1)
783 self.assertTrue(issubclass(w[-1].category, RuntimeWarning))
784 self.assertTrue('Callables passed to' in str(w[-1].message))
786 self.assertEqual(res, 34)
787 self.assertEqual(TestCallbacks.called, 1)
788 self.assertEqual(sys.getrefcount(callback), callback_refcount + 1)
790 # thaw will call the callback again,
791 # refcount will not go down without user_data parameter
792 self.assertEqual(Everything.test_callback_thaw_notifications(), 34)
793 self.assertEqual(TestCallbacks.called, 2)
794 self.assertEqual(sys.getrefcount(callback), callback_refcount + 1)
796 def test_callback_in_methods(self):
797 object_ = Everything.TestObj()
800 TestCallbacks.called = True
803 TestCallbacks.called = False
804 object_.instance_method_callback(callback)
805 self.assertTrue(TestCallbacks.called)
807 TestCallbacks.called = False
808 Everything.TestObj.static_method_callback(callback)
809 self.assertTrue(TestCallbacks.called)
811 def callbackWithUserData(user_data):
812 TestCallbacks.called += 1
815 TestCallbacks.called = 0
816 Everything.TestObj.new_callback(callbackWithUserData, None)
817 self.assertEqual(TestCallbacks.called, 1)
818 # Note: using "new_callback" adds the notification to the same global
819 # list as Everything.test_callback_destroy_notify, so thaw the list
820 # so we don't get confusion between tests.
821 self.assertEqual(Everything.test_callback_thaw_notifications(), 42)
822 self.assertEqual(TestCallbacks.called, 2)
824 def test_callback_none(self):
825 # make sure this doesn't assert or crash
826 Everything.test_simple_callback(None)
828 def test_callback_gerror(self):
830 self.assertEqual(error.message, 'regression test error')
831 self.assertTrue('g-io' in error.domain)
832 self.assertEqual(error.code, Gio.IOErrorEnum.NOT_SUPPORTED)
833 TestCallbacks.called = True
835 TestCallbacks.called = False
836 Everything.test_gerror_callback(callback)
837 self.assertTrue(TestCallbacks.called)
839 def test_callback_null_gerror(self):
841 self.assertEqual(error, None)
842 TestCallbacks.called = True
844 TestCallbacks.called = False
845 Everything.test_null_gerror_callback(callback)
846 self.assertTrue(TestCallbacks.called)
848 def test_callback_owned_gerror(self):
850 self.assertEqual(error.message, 'regression test owned error')
851 self.assertTrue('g-io' in error.domain)
852 self.assertEqual(error.code, Gio.IOErrorEnum.PERMISSION_DENIED)
853 TestCallbacks.called = True
855 TestCallbacks.called = False
856 Everything.test_owned_gerror_callback(callback)
857 self.assertTrue(TestCallbacks.called)
859 def test_callback_hashtable(self):
861 self.assertEqual(data, mydict)
863 TestCallbacks.called = True
865 mydict = {'foo': 1, 'bar': 2}
866 TestCallbacks.called = False
867 Everything.test_hash_table_callback(mydict, callback)
868 self.assertTrue(TestCallbacks.called)
869 self.assertEqual(mydict, {'foo': 1, 'bar': 2, 'new': 42})
872 @unittest.skipUnless(has_cairo, 'built without cairo support')
873 class TestClosures(unittest.TestCase):
874 def test_no_arg(self):
880 result = Everything.test_closure(callback)
881 self.assertTrue(self.called)
882 self.assertEqual(result, 42)
884 def test_int_arg(self):
890 result = Everything.test_closure_one_arg(callback, 42)
891 self.assertTrue(self.called)
892 self.assertEqual(result, 43)
894 def test_variant(self):
895 def callback(variant):
899 self.assertEqual(variant.get_type_string(), 'i')
900 return GLib.Variant('i', variant.get_int32() + 1)
903 result = Everything.test_closure_variant(callback, GLib.Variant('i', 42))
904 self.assertTrue(self.called)
905 self.assertEqual(result.get_type_string(), 'i')
906 self.assertEqual(result.get_int32(), 43)
909 result = Everything.test_closure_variant(callback, None)
910 self.assertTrue(self.called)
911 self.assertEqual(result, None)
914 self.assertRaises(TypeError, Everything.test_closure_variant, callback, 'foo')
915 self.assertFalse(self.called)
917 def test_variant_wrong_return_type(self):
918 def callback(variant):
924 # this does not directly raise an exception (see
925 # https://bugzilla.gnome.org/show_bug.cgi?id=616279)
926 result = Everything.test_closure_variant(callback, GLib.Variant('i', 42))
927 # ... but the result shouldn't be a string
928 self.assertEqual(result, None)
929 # and the error should be shown
930 self.assertEqual(sys.last_type, TypeError)
931 self.assertTrue('return value' in str(sys.last_value), sys.last_value)
934 @unittest.skipUnless(has_cairo, 'built without cairo support')
935 class TestProperties(unittest.TestCase):
937 def test_basic(self):
938 object_ = Everything.TestObj()
940 self.assertEqual(object_.props.int, 0)
941 object_.props.int = 42
942 self.assertTrue(isinstance(object_.props.int, int))
943 self.assertEqual(object_.props.int, 42)
945 self.assertEqual(object_.props.float, 0.0)
946 object_.props.float = 42.42
947 self.assertTrue(isinstance(object_.props.float, float))
948 self.assertAlmostEqual(object_.props.float, 42.42, places=5)
950 self.assertEqual(object_.props.double, 0.0)
951 object_.props.double = 42.42
952 self.assertTrue(isinstance(object_.props.double, float))
953 self.assertAlmostEqual(object_.props.double, 42.42, places=5)
955 self.assertEqual(object_.props.string, None)
956 object_.props.string = 'mec'
957 self.assertTrue(isinstance(object_.props.string, str))
958 self.assertEqual(object_.props.string, 'mec')
960 self.assertEqual(object_.props.gtype, GObject.TYPE_INVALID)
961 object_.props.gtype = int
962 self.assertEqual(object_.props.gtype, GObject.TYPE_INT)
964 def test_hash_table(self):
965 object_ = Everything.TestObj()
966 self.assertEqual(object_.props.hash_table, None)
968 object_.props.hash_table = {'mec': 56}
969 self.assertTrue(isinstance(object_.props.hash_table, dict))
970 self.assertEqual(list(object_.props.hash_table.items())[0], ('mec', 56))
973 object_ = Everything.TestObj()
974 self.assertEqual(object_.props.list, [])
976 object_.props.list = ['1', '2', '3']
977 self.assertTrue(isinstance(object_.props.list, list))
978 self.assertEqual(object_.props.list, ['1', '2', '3'])
980 def test_boxed(self):
981 object_ = Everything.TestObj()
982 self.assertEqual(object_.props.boxed, None)
984 boxed = Everything.TestBoxed()
986 object_.props.boxed = boxed
988 self.assertTrue(isinstance(object_.props.boxed, Everything.TestBoxed))
989 self.assertEqual(object_.props.boxed.some_int8, 42)
991 def test_boxed_alternative_constructor(self):
992 boxed = Everything.TestBoxed.new_alternative_constructor1(5)
993 self.assertEqual(boxed.some_int8, 5)
995 boxed = Everything.TestBoxed.new_alternative_constructor2(5, 3)
996 self.assertEqual(boxed.some_int8, 8)
998 boxed = Everything.TestBoxed.new_alternative_constructor3("-3")
999 self.assertEqual(boxed.some_int8, -3)
1001 def test_boxed_equality(self):
1002 boxed42 = Everything.TestBoxed.new_alternative_constructor1(42)
1003 boxed5 = Everything.TestBoxed.new_alternative_constructor1(5)
1004 boxed42_2 = Everything.TestBoxed.new_alternative_constructor2(41, 1)
1006 self.assertFalse(boxed42.equals(boxed5))
1007 self.assertTrue(boxed42.equals(boxed42_2))
1008 self.assertTrue(boxed42_2.equals(boxed42))
1009 self.assertTrue(boxed42.equals(boxed42))
1011 def test_boxed_c_equality(self):
1012 boxed = Everything.TestBoxedC()
1013 # TestBoxedC uses refcounting, so we know that
1014 # the pointer is the same when copied
1016 self.assertEqual(boxed, copy)
1017 self.assertNotEqual(id(boxed), id(copy))
1019 def test_gtype(self):
1020 object_ = Everything.TestObj()
1021 self.assertEqual(object_.props.gtype, GObject.TYPE_INVALID)
1022 object_.props.gtype = int
1023 self.assertEqual(object_.props.gtype, GObject.TYPE_INT)
1025 object_ = Everything.TestObj(gtype=int)
1026 self.assertEqual(object_.props.gtype, GObject.TYPE_INT)
1027 object_.props.gtype = str
1028 self.assertEqual(object_.props.gtype, GObject.TYPE_STRING)
1030 def test_parent_class(self):
1031 class A(Everything.TestObj):
1032 prop1 = GObject.Property(type=int)
1036 self.assertEqual(a.props.int, 20)
1038 # test parent property which needs introspection
1039 a.props.list = ("str1", "str2")
1040 self.assertEqual(a.props.list, ["str1", "str2"])
1043 @unittest.skipUnless(has_cairo, 'built without cairo support')
1044 class TestTortureProfile(unittest.TestCase):
1045 def test_torture_profile(self):
1049 object_ = Everything.TestObj()
1050 sys.stdout.write("\ttorture test 1 (10000 iterations): ")
1052 start_time = time.clock()
1053 for i in range(10000):
1054 (y, z, q) = object_.torture_signature_0(5000,
1058 end_time = time.clock()
1059 delta_time = end_time - start_time
1060 total_time += delta_time
1061 print("%f secs" % delta_time)
1063 sys.stdout.write("\ttorture test 2 (10000 iterations): ")
1065 start_time = time.clock()
1066 for i in range(10000):
1067 (y, z, q) = Everything.TestObj().torture_signature_0(
1068 5000, "Torture Test 2", 12345)
1070 end_time = time.clock()
1071 delta_time = end_time - start_time
1072 total_time += delta_time
1073 print("%f secs" % delta_time)
1075 sys.stdout.write("\ttorture test 3 (10000 iterations): ")
1076 start_time = time.clock()
1077 for i in range(10000):
1079 (y, z, q) = object_.torture_signature_1(
1080 5000, "Torture Test 3", 12345)
1083 end_time = time.clock()
1084 delta_time = end_time - start_time
1085 total_time += delta_time
1086 print("%f secs" % delta_time)
1088 sys.stdout.write("\ttorture test 4 (10000 iterations): ")
1090 def callback(userdata):
1093 userdata = [1, 2, 3, 4]
1094 start_time = time.clock()
1095 for i in range(10000):
1096 (y, z, q) = Everything.test_torture_signature_2(
1097 5000, callback, userdata, "Torture Test 4", 12345)
1098 end_time = time.clock()
1099 delta_time = end_time - start_time
1100 total_time += delta_time
1101 print("%f secs" % delta_time)
1103 print("\tTotal: %f sec" % total_time)
1106 @unittest.skipUnless(has_cairo, 'built without cairo support')
1107 class TestAdvancedInterfaces(unittest.TestCase):
1108 def test_array_objs(self):
1109 obj1, obj2 = Everything.test_array_fixed_out_objects()
1110 self.assertTrue(isinstance(obj1, Everything.TestObj))
1111 self.assertTrue(isinstance(obj2, Everything.TestObj))
1112 self.assertNotEqual(obj1, obj2)
1114 def test_obj_skip_return_val(self):
1115 obj = Everything.TestObj()
1116 ret = obj.skip_return_val(50, 42.0, 60, 2, 3)
1117 self.assertEqual(len(ret), 3)
1118 self.assertEqual(ret[0], 51)
1119 self.assertEqual(ret[1], 61)
1120 self.assertEqual(ret[2], 32)
1122 def test_obj_skip_return_val_no_out(self):
1123 obj = Everything.TestObj()
1124 # raises an error for 0, succeeds for any other value
1125 self.assertRaises(GLib.GError, obj.skip_return_val_no_out, 0)
1127 ret = obj.skip_return_val_no_out(1)
1128 self.assertEqual(ret, None)
1131 @unittest.skipUnless(has_cairo, 'built without cairo support')
1132 class TestSignals(unittest.TestCase):
1133 def test_object_param_signal(self):
1134 obj = Everything.TestObj()
1136 def callback(obj, obj_param):
1137 self.assertEqual(obj_param.props.int, 3)
1138 self.assertGreater(obj_param.__grefcount__, 1)
1142 obj.connect('sig-with-obj', callback)
1143 obj.emit_sig_with_obj()
1144 self.assertTrue(obj.called)
1146 def test_int64_param_from_py(self):
1147 obj = Everything.TestObj()
1149 def callback(obj, i):
1153 obj.callback_i = None
1154 obj.connect('sig-with-int64-prop', callback)
1155 rv = obj.emit('sig-with-int64-prop', GObject.G_MAXINT64)
1156 self.assertEqual(rv, GObject.G_MAXINT64)
1157 self.assertEqual(obj.callback_i, GObject.G_MAXINT64)
1159 def test_uint64_param_from_py(self):
1160 obj = Everything.TestObj()
1162 def callback(obj, i):
1166 obj.callback_i = None
1167 obj.connect('sig-with-uint64-prop', callback)
1168 rv = obj.emit('sig-with-uint64-prop', GObject.G_MAXUINT64)
1169 self.assertEqual(rv, GObject.G_MAXUINT64)
1170 self.assertEqual(obj.callback_i, GObject.G_MAXUINT64)
1172 def test_int64_param_from_c(self):
1173 obj = Everything.TestObj()
1175 def callback(obj, i):
1179 obj.callback_i = None
1181 obj.connect('sig-with-int64-prop', callback)
1182 obj.emit_sig_with_int64()
1183 self.assertEqual(obj.callback_i, GObject.G_MAXINT64)
1185 def test_uint64_param_from_c(self):
1186 obj = Everything.TestObj()
1188 def callback(obj, i):
1192 obj.callback_i = None
1194 obj.connect('sig-with-uint64-prop', callback)
1195 obj.emit_sig_with_uint64()
1196 self.assertEqual(obj.callback_i, GObject.G_MAXUINT64)
1199 @unittest.skipUnless(has_cairo, 'built without cairo support')
1200 @unittest.skipUnless(Gtk, 'Gtk not available')
1201 class TestPango(unittest.TestCase):
1202 def test_cairo_font_options(self):
1203 screen = Gtk.Window().get_screen()
1204 font_opts = screen.get_font_options()
1205 self.assertEqual(type(font_opts.get_subpixel_order()), int)