Imported Upstream version 3.3.1
[platform/upstream/pygobject2.git] / tests / test_everything.py
1 # -*- Mode: Python; py-indent-offset: 4 -*-
2 # coding=utf-8
3 # vim: tabstop=4 shiftwidth=4 expandtab
4
5 import unittest
6
7 import sys
8 sys.path.insert(0, "../")
9 from sys import getrefcount
10
11 import copy
12 import cairo
13
14 from gi.repository import GObject
15 from gi.repository import GLib
16 from gi.repository import Gio
17 from gi.repository import Regress as Everything
18
19 if sys.version_info < (3, 0):
20     UNICHAR = "\xe2\x99\xa5"
21     PY2_UNICODE_UNICHAR = unicode(UNICHAR, 'UTF-8')
22 else:
23     UNICHAR = "♥"
24
25
26 class TestEverything(unittest.TestCase):
27
28     def test_cairo_context(self):
29         context = Everything.test_cairo_context_full_return()
30         self.assertTrue(isinstance(context, cairo.Context))
31
32         surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10)
33         context = cairo.Context(surface)
34         Everything.test_cairo_context_none_in(context)
35
36     def test_cairo_surface(self):
37         surface = Everything.test_cairo_surface_none_return()
38         self.assertTrue(isinstance(surface, cairo.ImageSurface))
39         self.assertTrue(isinstance(surface, cairo.Surface))
40         self.assertEqual(surface.get_format(), cairo.FORMAT_ARGB32)
41         self.assertEqual(surface.get_width(), 10)
42         self.assertEqual(surface.get_height(), 10)
43
44         surface = Everything.test_cairo_surface_full_return()
45         self.assertTrue(isinstance(surface, cairo.ImageSurface))
46         self.assertTrue(isinstance(surface, cairo.Surface))
47         self.assertEqual(surface.get_format(), cairo.FORMAT_ARGB32)
48         self.assertEqual(surface.get_width(), 10)
49         self.assertEqual(surface.get_height(), 10)
50
51         surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10)
52         Everything.test_cairo_surface_none_in(surface)
53
54         surface = Everything.test_cairo_surface_full_out()
55         self.assertTrue(isinstance(surface, cairo.ImageSurface))
56         self.assertTrue(isinstance(surface, cairo.Surface))
57         self.assertEqual(surface.get_format(), cairo.FORMAT_ARGB32)
58         self.assertEqual(surface.get_width(), 10)
59         self.assertEqual(surface.get_height(), 10)
60
61     def test_unichar(self):
62         self.assertEqual("c", Everything.test_unichar("c"))
63
64         if sys.version_info < (3, 0):
65             self.assertEqual(UNICHAR, Everything.test_unichar(PY2_UNICODE_UNICHAR))
66         self.assertEqual(UNICHAR, Everything.test_unichar(UNICHAR))
67         self.assertRaises(TypeError, Everything.test_unichar, "")
68         self.assertRaises(TypeError, Everything.test_unichar, "morethanonechar")
69
70     def test_floating(self):
71         e = Everything.TestFloating()
72         self.assertEqual(e.__grefcount__, 1)
73
74         e = GObject.new(Everything.TestFloating)
75         self.assertEqual(e.__grefcount__, 1)
76
77         e = Everything.TestFloating.new()
78         self.assertEqual(e.__grefcount__, 1)
79
80     def test_caller_allocates(self):
81         struct_a = Everything.TestStructA()
82         struct_a.some_int = 10
83         struct_a.some_int8 = 21
84         struct_a.some_double = 3.14
85         struct_a.some_enum = Everything.TestEnum.VALUE3
86
87         struct_a_clone = struct_a.clone()
88         self.assertTrue(struct_a != struct_a_clone)
89         self.assertEqual(struct_a.some_int, struct_a_clone.some_int)
90         self.assertEqual(struct_a.some_int8, struct_a_clone.some_int8)
91         self.assertEqual(struct_a.some_double, struct_a_clone.some_double)
92         self.assertEqual(struct_a.some_enum, struct_a_clone.some_enum)
93
94         struct_b = Everything.TestStructB()
95         struct_b.some_int8 = 8
96         struct_b.nested_a.some_int = 20
97         struct_b.nested_a.some_int8 = 12
98         struct_b.nested_a.some_double = 333.3333
99         struct_b.nested_a.some_enum = Everything.TestEnum.VALUE2
100
101         struct_b_clone = struct_b.clone()
102         self.assertTrue(struct_b != struct_b_clone)
103         self.assertEqual(struct_b.some_int8, struct_b_clone.some_int8)
104         self.assertEqual(struct_b.nested_a.some_int, struct_b_clone.nested_a.some_int)
105         self.assertEqual(struct_b.nested_a.some_int8, struct_b_clone.nested_a.some_int8)
106         self.assertEqual(struct_b.nested_a.some_double, struct_b_clone.nested_a.some_double)
107         self.assertEqual(struct_b.nested_a.some_enum, struct_b_clone.nested_a.some_enum)
108
109     def test_wrong_type_of_arguments(self):
110         try:
111             Everything.test_int8()
112         except TypeError:
113             (e_type, e) = sys.exc_info()[:2]
114             self.assertEqual(e.args, ("test_int8() takes exactly 1 argument (0 given)",))
115
116     def test_gtypes(self):
117         gchararray_gtype = GObject.type_from_name('gchararray')
118         gtype = Everything.test_gtype(str)
119         self.assertEqual(gchararray_gtype, gtype)
120         gtype = Everything.test_gtype('gchararray')
121         self.assertEqual(gchararray_gtype, gtype)
122         gobject_gtype = GObject.GObject.__gtype__
123         gtype = Everything.test_gtype(GObject.GObject)
124         self.assertEqual(gobject_gtype, gtype)
125         gtype = Everything.test_gtype('GObject')
126         self.assertEqual(gobject_gtype, gtype)
127         self.assertRaises(TypeError, Everything.test_gtype, 'invalidgtype')
128
129         class NotARegisteredClass(object):
130             pass
131
132         self.assertRaises(TypeError, Everything.test_gtype, NotARegisteredClass)
133
134         class ARegisteredClass(GObject.GObject):
135             __gtype_name__ = 'EverythingTestsARegisteredClass'
136
137         gtype = Everything.test_gtype('EverythingTestsARegisteredClass')
138         self.assertEqual(ARegisteredClass.__gtype__, gtype)
139         gtype = Everything.test_gtype(ARegisteredClass)
140         self.assertEqual(ARegisteredClass.__gtype__, gtype)
141         self.assertRaises(TypeError, Everything.test_gtype, 'ARegisteredClass')
142
143     def test_dir(self):
144         attr_list = dir(Everything)
145
146         # test that typelib attributes are listed
147         self.assertTrue('TestStructA' in attr_list)
148
149         # test that class attributes and methods are listed
150         self.assertTrue('__class__' in attr_list)
151         self.assertTrue('__dir__' in attr_list)
152         self.assertTrue('__repr__' in attr_list)
153
154         # test that instance members are listed
155         self.assertTrue('_namespace' in attr_list)
156         self.assertTrue('_version' in attr_list)
157
158         # test that there are no duplicates returned
159         self.assertEqual(len(attr_list), len(set(attr_list)))
160
161     def test_ptrarray(self):
162         # transfer container
163         result = Everything.test_garray_container_return()
164         self.assertEqual(result, ['regress'])
165         result = None
166
167         # transfer full
168         result = Everything.test_garray_full_return()
169         self.assertEqual(result, ['regress'])
170         result = None
171
172     def test_hash_return(self):
173         result = Everything.test_ghash_gvalue_return()
174         self.assertEqual(result['integer'], 12)
175         self.assertEqual(result['boolean'], True)
176         self.assertEqual(result['string'], 'some text')
177         self.assertEqual(result['strings'], ['first', 'second', 'third'])
178         self.assertEqual(result['flags'], Everything.TestFlags.FLAG1 | Everything.TestFlags.FLAG3)
179         self.assertEqual(result['enum'], Everything.TestEnum.VALUE2)
180         result = None
181
182     def test_hash_in(self):
183         # specifying a simple string array for "strings" does not work due to
184         # https://bugzilla.gnome.org/show_bug.cgi?id=666636
185         # workaround by explicitly building a GStrv object
186         class GStrv(list):
187             __gtype__ = GObject.type_from_name('GStrv')
188
189         data = {'integer': 12,
190                 'boolean': True,
191                 'string': 'some text',
192                 'strings': GStrv(['first', 'second', 'third']),
193                 'flags': Everything.TestFlags.FLAG1 | Everything.TestFlags.FLAG3,
194                 'enum': Everything.TestEnum.VALUE2,
195                }
196         Everything.test_ghash_gvalue_in(data)
197         data = None
198
199     def test_struct_gpointer(self):
200         l1 = GLib.List()
201         self.assertEqual(l1.data, None)
202         init_refcount = getrefcount(l1)
203
204         l1.data = 'foo'
205         self.assertEqual(l1.data, 'foo')
206
207         l2 = l1
208         self.assertEqual(l1.data, l2.data)
209         self.assertEqual(getrefcount(l1), init_refcount + 1)
210
211         l3 = copy.copy(l1)
212         l3.data = 'bar'
213         self.assertEqual(l1.data, 'foo')
214         self.assertEqual(l2.data, 'foo')
215         self.assertEqual(l3.data, 'bar')
216         self.assertEqual(getrefcount(l1), init_refcount + 1)
217         self.assertEqual(getrefcount(l3), init_refcount)
218
219
220 class TestNullableArgs(unittest.TestCase):
221     def test_in_nullable_hash(self):
222         Everything.test_ghash_null_in(None)
223
224     def test_in_nullable_list(self):
225         Everything.test_gslist_null_in(None)
226         Everything.test_glist_null_in(None)
227         Everything.test_gslist_null_in([])
228         Everything.test_glist_null_in([])
229
230     def test_in_nullable_array(self):
231         Everything.test_array_int_null_in(None)
232         Everything.test_array_int_null_in([])
233
234     def test_in_nullable_string(self):
235         Everything.test_utf8_null_in(None)
236
237     def test_in_nullable_object(self):
238         Everything.func_obj_null_in(None)
239
240     def test_out_nullable_hash(self):
241         self.assertEqual(None, Everything.test_ghash_null_out())
242
243     def test_out_nullable_list(self):
244         self.assertEqual([], Everything.test_gslist_null_out())
245         self.assertEqual([], Everything.test_glist_null_out())
246
247     def test_out_nullable_array(self):
248         self.assertEqual([], Everything.test_array_int_null_out())
249
250     def test_out_nullable_string(self):
251         self.assertEqual(None, Everything.test_utf8_null_out())
252
253     def test_out_nullable_object(self):
254         self.assertEqual(None, Everything.TestObj.null_out())
255
256
257 class TestCallbacks(unittest.TestCase):
258     called = False
259     main_loop = GObject.MainLoop()
260
261     def test_callback(self):
262         TestCallbacks.called = False
263
264         def callback():
265             TestCallbacks.called = True
266
267         Everything.test_simple_callback(callback)
268         self.assertTrue(TestCallbacks.called)
269
270     def test_callback_exception(self):
271         """
272         This test ensures that we get errors from callbacks correctly
273         and in particular that we do not segv when callbacks fail
274         """
275         def callback():
276             x = 1 / 0
277             self.fail('unexpected surviving zero divsion:' + str(x))
278
279         # note that we do NOT expect the ZeroDivisionError to be propagated
280         # through from the callback, as it crosses the Python<->C boundary
281         # twice. (See GNOME #616279)
282         Everything.test_simple_callback(callback)
283
284     def test_double_callback_exception(self):
285         """
286         This test ensures that we get errors from callbacks correctly
287         and in particular that we do not segv when callbacks fail
288         """
289         def badcallback():
290             x = 1 / 0
291             self.fail('unexpected surviving zero divsion:' + str(x))
292
293         def callback():
294             Everything.test_boolean(True)
295             Everything.test_boolean(False)
296             Everything.test_simple_callback(badcallback())
297
298         # note that we do NOT expect the ZeroDivisionError to be propagated
299         # through from the callback, as it crosses the Python<->C boundary
300         # twice. (See GNOME #616279)
301         Everything.test_simple_callback(callback)
302
303     def test_return_value_callback(self):
304         TestCallbacks.called = False
305
306         def callback():
307             TestCallbacks.called = True
308             return 44
309
310         self.assertEqual(Everything.test_callback(callback), 44)
311         self.assertTrue(TestCallbacks.called)
312
313     def test_callback_async(self):
314         TestCallbacks.called = False
315
316         def callback(foo):
317             TestCallbacks.called = True
318             return foo
319
320         Everything.test_callback_async(callback, 44)
321         i = Everything.test_callback_thaw_async()
322         self.assertEqual(44, i)
323         self.assertTrue(TestCallbacks.called)
324
325     def test_callback_scope_call(self):
326         TestCallbacks.called = 0
327
328         def callback():
329             TestCallbacks.called += 1
330             return 0
331
332         Everything.test_multi_callback(callback)
333         self.assertEqual(TestCallbacks.called, 2)
334
335     def test_callback_userdata(self):
336         TestCallbacks.called = 0
337
338         def callback(userdata):
339             self.assertEqual(userdata, "Test%d" % TestCallbacks.called)
340             TestCallbacks.called += 1
341             return TestCallbacks.called
342
343         for i in range(100):
344             val = Everything.test_callback_user_data(callback, "Test%d" % i)
345             self.assertEqual(val, i + 1)
346
347         self.assertEqual(TestCallbacks.called, 100)
348
349     def test_callback_userdata_refcount(self):
350         TestCallbacks.called = False
351
352         def callback(userdata):
353             TestCallbacks.called = True
354             return 1
355
356         ud = "Test User Data"
357
358         start_ref_count = getrefcount(ud)
359         for i in range(100):
360             Everything.test_callback_destroy_notify(callback, ud)
361
362         Everything.test_callback_thaw_notifications()
363         end_ref_count = getrefcount(ud)
364
365         self.assertEqual(start_ref_count, end_ref_count)
366
367     def test_async_ready_callback(self):
368         TestCallbacks.called = False
369         TestCallbacks.main_loop = GObject.MainLoop()
370
371         def callback(obj, result, user_data):
372             TestCallbacks.main_loop.quit()
373             TestCallbacks.called = True
374
375         Everything.test_async_ready_callback(callback)
376
377         TestCallbacks.main_loop.run()
378
379         self.assertTrue(TestCallbacks.called)
380
381     def test_callback_destroy_notify(self):
382         def callback(user_data):
383             TestCallbacks.called = True
384             return 42
385
386         TestCallbacks.called = False
387         self.assertEqual(Everything.test_callback_destroy_notify(callback, 42), 42)
388         self.assertTrue(TestCallbacks.called)
389         self.assertEqual(Everything.test_callback_thaw_notifications(), 42)
390
391     def test_callback_in_methods(self):
392         object_ = Everything.TestObj()
393
394         def callback():
395             TestCallbacks.called = True
396             return 42
397
398         TestCallbacks.called = False
399         object_.instance_method_callback(callback)
400         self.assertTrue(TestCallbacks.called)
401
402         TestCallbacks.called = False
403         Everything.TestObj.static_method_callback(callback)
404         self.assertTrue(TestCallbacks.called)
405
406         def callbackWithUserData(user_data):
407             TestCallbacks.called = True
408             return 42
409
410         TestCallbacks.called = False
411         Everything.TestObj.new_callback(callbackWithUserData, None)
412         self.assertTrue(TestCallbacks.called)
413
414     def test_callback_none(self):
415         # make sure this doesn't assert or crash
416         Everything.test_simple_callback(None)
417
418     def test_callback_gerror(self):
419         def callback(error):
420             self.assertEqual(error.message, 'regression test error')
421             self.assertTrue('g-io' in error.domain)
422             self.assertEqual(error.code, Gio.IOErrorEnum.NOT_SUPPORTED)
423             TestCallbacks.called = True
424
425         TestCallbacks.called = False
426         Everything.test_gerror_callback(callback)
427         self.assertTrue(TestCallbacks.called)
428
429     def test_callback_null_gerror(self):
430         def callback(error):
431             self.assertEqual(error, None)
432             TestCallbacks.called = True
433
434         TestCallbacks.called = False
435         Everything.test_null_gerror_callback(callback)
436         self.assertTrue(TestCallbacks.called)
437
438     def test_callback_owned_gerror(self):
439         def callback(error):
440             self.assertEqual(error.message, 'regression test owned error')
441             self.assertTrue('g-io' in error.domain)
442             self.assertEqual(error.code, Gio.IOErrorEnum.PERMISSION_DENIED)
443             TestCallbacks.called = True
444
445         TestCallbacks.called = False
446         Everything.test_owned_gerror_callback(callback)
447         self.assertTrue(TestCallbacks.called)
448
449     def test_callback_hashtable(self):
450         def callback(data):
451             self.assertEqual(data, mydict)
452             mydict['new'] = 42
453             TestCallbacks.called = True
454
455         mydict = {'foo': 1, 'bar': 2}
456         TestCallbacks.called = False
457         Everything.test_hash_table_callback(mydict, callback)
458         self.assertTrue(TestCallbacks.called)
459         self.assertEqual(mydict, {'foo': 1, 'bar': 2, 'new': 42})
460
461
462 class TestClosures(unittest.TestCase):
463     def test_int_arg(self):
464         def callback(num):
465             self.called = True
466             return num + 1
467
468         self.called = False
469         result = Everything.test_closure_one_arg(callback, 42)
470         self.assertTrue(self.called)
471         self.assertEqual(result, 43)
472
473     # https://bugzilla.gnome.org/show_bug.cgi?id=656554
474
475     @unittest.expectedFailure
476     def test_variant(self):
477         def callback(variant):
478             self.assertEqual(variant.get_type_string(), 'i')
479             self.called = True
480             return GLib.Variant('i', variant.get_int32() + 1)
481
482         self.called = False
483         result = Everything.test_closure_variant(callback, GLib.Variant('i', 42))
484         self.assertTrue(self.called)
485         self.assertEqual(result.get_type_string(), 'i')
486         self.assertEqual(result.get_int32(), 43)
487
488
489 class TestProperties(unittest.TestCase):
490
491     def test_basic(self):
492         object_ = Everything.TestObj()
493
494         self.assertEqual(object_.props.int, 0)
495         object_.props.int = 42
496         self.assertTrue(isinstance(object_.props.int, int))
497         self.assertEqual(object_.props.int, 42)
498
499         self.assertEqual(object_.props.float, 0.0)
500         object_.props.float = 42.42
501         self.assertTrue(isinstance(object_.props.float, float))
502         self.assertAlmostEquals(object_.props.float, 42.42, places=5)
503
504         self.assertEqual(object_.props.double, 0.0)
505         object_.props.double = 42.42
506         self.assertTrue(isinstance(object_.props.double, float))
507         self.assertAlmostEquals(object_.props.double, 42.42, places=5)
508
509         self.assertEqual(object_.props.string, None)
510         object_.props.string = 'mec'
511         self.assertTrue(isinstance(object_.props.string, str))
512         self.assertEqual(object_.props.string, 'mec')
513
514         self.assertEqual(object_.props.gtype, GObject.TYPE_INVALID)
515         object_.props.gtype = int
516         self.assertEqual(object_.props.gtype, GObject.TYPE_INT)
517
518     def test_hash_table(self):
519         object_ = Everything.TestObj()
520         self.assertEqual(object_.props.hash_table, None)
521
522         object_.props.hash_table = {'mec': 56}
523         self.assertTrue(isinstance(object_.props.hash_table, dict))
524         self.assertEqual(list(object_.props.hash_table.items())[0], ('mec', 56))
525
526     def test_list(self):
527         object_ = Everything.TestObj()
528         self.assertEqual(object_.props.list, [])
529
530         object_.props.list = ['1', '2', '3']
531         self.assertTrue(isinstance(object_.props.list, list))
532         self.assertEqual(object_.props.list, ['1', '2', '3'])
533
534     def test_boxed(self):
535         object_ = Everything.TestObj()
536         self.assertEqual(object_.props.boxed, None)
537
538         boxed = Everything.TestBoxed()
539         boxed.some_int8 = 42
540         object_.props.boxed = boxed
541
542         self.assertTrue(isinstance(object_.props.boxed, Everything.TestBoxed))
543         self.assertEqual(object_.props.boxed.some_int8, 42)
544
545     def test_gtype(self):
546         object_ = Everything.TestObj()
547         self.assertEqual(object_.props.gtype, GObject.TYPE_INVALID)
548         object_.props.gtype = int
549         self.assertEqual(object_.props.gtype, GObject.TYPE_INT)
550
551         object_ = Everything.TestObj(gtype=int)
552         self.assertEqual(object_.props.gtype, GObject.TYPE_INT)
553         object_.props.gtype = str
554         self.assertEqual(object_.props.gtype, GObject.TYPE_STRING)
555
556
557 class TestTortureProfile(unittest.TestCase):
558     def test_torture_profile(self):
559         import time
560         total_time = 0
561         print("")
562         object_ = Everything.TestObj()
563         sys.stdout.write("\ttorture test 1 (10000 iterations): ")
564
565         start_time = time.clock()
566         for i in range(10000):
567             (y, z, q) = object_.torture_signature_0(5000,
568                                                     "Torture Test 1",
569                                                     12345)
570
571         end_time = time.clock()
572         delta_time = end_time - start_time
573         total_time += delta_time
574         print("%f secs" % delta_time)
575
576         sys.stdout.write("\ttorture test 2 (10000 iterations): ")
577
578         start_time = time.clock()
579         for i in range(10000):
580             (y, z, q) = Everything.TestObj().torture_signature_0(
581                 5000, "Torture Test 2", 12345)
582
583         end_time = time.clock()
584         delta_time = end_time - start_time
585         total_time += delta_time
586         print("%f secs" % delta_time)
587
588         sys.stdout.write("\ttorture test 3 (10000 iterations): ")
589         start_time = time.clock()
590         for i in range(10000):
591             try:
592                 (y, z, q) = object_.torture_signature_1(
593                     5000, "Torture Test 3", 12345)
594             except:
595                 pass
596         end_time = time.clock()
597         delta_time = end_time - start_time
598         total_time += delta_time
599         print("%f secs" % delta_time)
600
601         sys.stdout.write("\ttorture test 4 (10000 iterations): ")
602
603         def callback(userdata):
604             pass
605
606         userdata = [1, 2, 3, 4]
607         start_time = time.clock()
608         for i in range(10000):
609             (y, z, q) = Everything.test_torture_signature_2(
610                 5000, callback, userdata, "Torture Test 4", 12345)
611         end_time = time.clock()
612         delta_time = end_time - start_time
613         total_time += delta_time
614         print("%f secs" % delta_time)
615         print("\t====")
616         print("\tTotal: %f sec" % total_time)
617
618
619 class TestAdvancedInterfaces(unittest.TestCase):
620     def test_array_objs(self):
621         obj1, obj2 = Everything.test_array_fixed_out_objects()
622         self.assertTrue(isinstance(obj1, Everything.TestObj))
623         self.assertTrue(isinstance(obj2, Everything.TestObj))
624         self.assertNotEqual(obj1, obj2)
625
626     def test_obj_skip_return_val(self):
627         obj = Everything.TestObj()
628         ret = obj.skip_return_val(50, 42.0, 60, 2, 3)
629         self.assertEqual(len(ret), 3)
630         self.assertEqual(ret[0], 51)
631         self.assertEqual(ret[1], 61)
632         self.assertEqual(ret[2], 32)
633
634     def test_obj_skip_return_val_no_out(self):
635         obj = Everything.TestObj()
636         # raises an error for 0, succeeds for any other value
637         self.assertRaises(GLib.GError, obj.skip_return_val_no_out, 0)
638
639         ret = obj.skip_return_val_no_out(1)
640         self.assertEqual(ret, None)
641
642
643 class TestSignals(unittest.TestCase):
644     def test_object_param_signal(self):
645         obj = Everything.TestObj()
646
647         def callback(obj, obj_param):
648             self.assertEqual(obj_param.props.int, 3)
649             self.assertGreater(obj_param.__grefcount__, 1)
650
651         obj.connect('sig-with-obj', callback)
652         obj.emit_sig_with_obj()