9b4f5f73d4bca3a3f6c9e47137a23fca1b42833b
[platform/upstream/pygobject2.git] / tests / test_gobject.py
1 # -*- Mode: Python -*-
2
3 import sys
4 import gc
5 import unittest
6 import warnings
7
8 from gi.repository import GObject, GLib
9 from gi import PyGIDeprecationWarning
10 from gi.module import get_introspection_module
11 from gi._gobject import _gobject
12
13 import testhelper
14
15
16 class TestGObjectAPI(unittest.TestCase):
17     def test_gobject_inheritance(self):
18         # GObject.Object is a class hierarchy as follows:
19         # overrides.Object -> introspection.Object -> static.GObject
20         GIObjectModule = get_introspection_module('GObject')
21         self.assertTrue(issubclass(GObject.Object, GIObjectModule.Object))
22         self.assertTrue(issubclass(GIObjectModule.Object, _gobject.GObject))
23
24         self.assertEqual(_gobject.GObject.__gtype__, GObject.TYPE_OBJECT)
25         self.assertEqual(GIObjectModule.Object.__gtype__, GObject.TYPE_OBJECT)
26         self.assertEqual(GObject.Object.__gtype__, GObject.TYPE_OBJECT)
27
28         # The pytype wrapper should hold the outer most Object class from overrides.
29         self.assertEqual(GObject.TYPE_OBJECT.pytype, GObject.Object)
30
31     @unittest.skipIf(sys.version_info[:2] < (2, 7), 'Python 2.7 is required')
32     def test_gobject_unsupported_overrides(self):
33         obj = GObject.Object()
34
35         with self.assertRaisesRegex(RuntimeError, 'Data access methods are unsupported.*'):
36             obj.get_data()
37
38         with self.assertRaisesRegex(RuntimeError, 'This method is currently unsupported.*'):
39             obj.force_floating()
40
41     def test_compat_api(self):
42         with warnings.catch_warnings(record=True) as w:
43             warnings.simplefilter('always')
44             # GObject formerly exposed a lot of GLib's functions
45             self.assertEqual(GObject.markup_escape_text('foo'), 'foo')
46
47             ml = GObject.MainLoop()
48             self.assertFalse(ml.is_running())
49
50             context = GObject.main_context_default()
51             self.assertTrue(context.pending() in [False, True])
52
53             context = GObject.MainContext()
54             self.assertFalse(context.pending())
55
56             self.assertTrue(issubclass(w[0].category, PyGIDeprecationWarning))
57             self.assertTrue('GLib.markup_escape_text' in str(w[0]), str(w[0]))
58
59             self.assertLess(GObject.PRIORITY_HIGH, GObject.PRIORITY_DEFAULT)
60
61     def test_min_max_int(self):
62         self.assertEqual(GObject.G_MAXINT16, 2 ** 15 - 1)
63         self.assertEqual(GObject.G_MININT16, -2 ** 15)
64         self.assertEqual(GObject.G_MAXUINT16, 2 ** 16 - 1)
65
66         self.assertEqual(GObject.G_MAXINT32, 2 ** 31 - 1)
67         self.assertEqual(GObject.G_MININT32, -2 ** 31)
68         self.assertEqual(GObject.G_MAXUINT32, 2 ** 32 - 1)
69
70         self.assertEqual(GObject.G_MAXINT64, 2 ** 63 - 1)
71         self.assertEqual(GObject.G_MININT64, -2 ** 63)
72         self.assertEqual(GObject.G_MAXUINT64, 2 ** 64 - 1)
73
74
75 class TestReferenceCounting(unittest.TestCase):
76     def test_regular_object(self):
77         obj = GObject.GObject()
78         self.assertEqual(obj.__grefcount__, 1)
79
80         obj = GObject.new(GObject.GObject)
81         self.assertEqual(obj.__grefcount__, 1)
82
83     def test_floating(self):
84         obj = testhelper.Floating()
85         self.assertEqual(obj.__grefcount__, 1)
86
87         obj = GObject.new(testhelper.Floating)
88         self.assertEqual(obj.__grefcount__, 1)
89
90     def test_owned_by_library(self):
91         # Upon creation, the refcount of the object should be 2:
92         # - someone already has a reference on the new object.
93         # - the python wrapper should hold its own reference.
94         obj = testhelper.OwnedByLibrary()
95         self.assertEqual(obj.__grefcount__, 2)
96
97         # We ask the library to release its reference, so the only
98         # remaining ref should be our wrapper's. Once the wrapper
99         # will run out of scope, the object will get finalized.
100         obj.release()
101         self.assertEqual(obj.__grefcount__, 1)
102
103     def test_owned_by_library_out_of_scope(self):
104         obj = testhelper.OwnedByLibrary()
105         self.assertEqual(obj.__grefcount__, 2)
106
107         # We are manually taking the object out of scope. This means
108         # that our wrapper has been freed, and its reference dropped. We
109         # cannot check it but the refcount should now be 1 (the ref held
110         # by the library is still there, we didn't call release()
111         obj = None
112
113         # When we get the object back from the lib, the wrapper is
114         # re-created, so our refcount will be 2 once again.
115         obj = testhelper.owned_by_library_get_instance_list()[0]
116         self.assertEqual(obj.__grefcount__, 2)
117
118         obj.release()
119         self.assertEqual(obj.__grefcount__, 1)
120
121     def test_owned_by_library_using_gobject_new(self):
122         # Upon creation, the refcount of the object should be 2:
123         # - someone already has a reference on the new object.
124         # - the python wrapper should hold its own reference.
125         obj = GObject.new(testhelper.OwnedByLibrary)
126         self.assertEqual(obj.__grefcount__, 2)
127
128         # We ask the library to release its reference, so the only
129         # remaining ref should be our wrapper's. Once the wrapper
130         # will run out of scope, the object will get finalized.
131         obj.release()
132         self.assertEqual(obj.__grefcount__, 1)
133
134     def test_owned_by_library_out_of_scope_using_gobject_new(self):
135         obj = GObject.new(testhelper.OwnedByLibrary)
136         self.assertEqual(obj.__grefcount__, 2)
137
138         # We are manually taking the object out of scope. This means
139         # that our wrapper has been freed, and its reference dropped. We
140         # cannot check it but the refcount should now be 1 (the ref held
141         # by the library is still there, we didn't call release()
142         obj = None
143
144         # When we get the object back from the lib, the wrapper is
145         # re-created, so our refcount will be 2 once again.
146         obj = testhelper.owned_by_library_get_instance_list()[0]
147         self.assertEqual(obj.__grefcount__, 2)
148
149         obj.release()
150         self.assertEqual(obj.__grefcount__, 1)
151
152     def test_floating_and_sunk(self):
153         # Upon creation, the refcount of the object should be 2:
154         # - someone already has a reference on the new object.
155         # - the python wrapper should hold its own reference.
156         obj = testhelper.FloatingAndSunk()
157         self.assertEqual(obj.__grefcount__, 2)
158
159         # We ask the library to release its reference, so the only
160         # remaining ref should be our wrapper's. Once the wrapper
161         # will run out of scope, the object will get finalized.
162         obj.release()
163         self.assertEqual(obj.__grefcount__, 1)
164
165     def test_floating_and_sunk_out_of_scope(self):
166         obj = testhelper.FloatingAndSunk()
167         self.assertEqual(obj.__grefcount__, 2)
168
169         # We are manually taking the object out of scope. This means
170         # that our wrapper has been freed, and its reference dropped. We
171         # cannot check it but the refcount should now be 1 (the ref held
172         # by the library is still there, we didn't call release()
173         obj = None
174
175         # When we get the object back from the lib, the wrapper is
176         # re-created, so our refcount will be 2 once again.
177         obj = testhelper.floating_and_sunk_get_instance_list()[0]
178         self.assertEqual(obj.__grefcount__, 2)
179
180         obj.release()
181         self.assertEqual(obj.__grefcount__, 1)
182
183     def test_floating_and_sunk_using_gobject_new(self):
184         # Upon creation, the refcount of the object should be 2:
185         # - someone already has a reference on the new object.
186         # - the python wrapper should hold its own reference.
187         obj = GObject.new(testhelper.FloatingAndSunk)
188         self.assertEqual(obj.__grefcount__, 2)
189
190         # We ask the library to release its reference, so the only
191         # remaining ref should be our wrapper's. Once the wrapper
192         # will run out of scope, the object will get finalized.
193         obj.release()
194         self.assertEqual(obj.__grefcount__, 1)
195
196     def test_floating_and_sunk_out_of_scope_using_gobject_new(self):
197         obj = GObject.new(testhelper.FloatingAndSunk)
198         self.assertEqual(obj.__grefcount__, 2)
199
200         # We are manually taking the object out of scope. This means
201         # that our wrapper has been freed, and its reference dropped. We
202         # cannot check it but the refcount should now be 1 (the ref held
203         # by the library is still there, we didn't call release()
204         obj = None
205
206         # When we get the object back from the lib, the wrapper is
207         # re-created, so our refcount will be 2 once again.
208         obj = testhelper.floating_and_sunk_get_instance_list()[0]
209         self.assertEqual(obj.__grefcount__, 2)
210
211         obj.release()
212         self.assertEqual(obj.__grefcount__, 1)
213
214     def test_uninitialized_object(self):
215         class Obj(GObject.GObject):
216             def __init__(self):
217                 x = self.__grefcount__
218                 super(Obj, self).__init__()
219                 assert x >= 0  # quiesce pyflakes
220
221         # Accessing __grefcount__ before the object is initialized is wrong.
222         # Ensure we get a proper exception instead of a crash.
223         self.assertRaises(TypeError, Obj)
224
225
226 class A(GObject.GObject):
227     def __init__(self):
228         super(A, self).__init__()
229
230
231 class TestPythonReferenceCounting(unittest.TestCase):
232     # Newly created instances should alwayshave two references: one for
233     # the GC, and one for the bound variable in the local scope.
234
235     def test_new_instance_has_two_refs(self):
236         obj = GObject.GObject()
237         self.assertEqual(sys.getrefcount(obj), 2)
238
239     def test_new_instance_has_two_refs_using_gobject_new(self):
240         obj = GObject.new(GObject.GObject)
241         self.assertEqual(sys.getrefcount(obj), 2)
242
243     def test_new_subclass_instance_has_two_refs(self):
244         obj = A()
245         self.assertEqual(sys.getrefcount(obj), 2)
246
247     def test_new_subclass_instance_has_two_refs_using_gobject_new(self):
248         obj = GObject.new(A)
249         self.assertEqual(sys.getrefcount(obj), 2)
250
251
252 class TestContextManagers(unittest.TestCase):
253     class ContextTestObject(GObject.GObject):
254         prop = GObject.Property(default=0, type=int)
255
256     def on_prop_set(self, obj, prop):
257         # Handler which tracks property changed notifications.
258         self.tracking.append(obj.get_property(prop.name))
259
260     def setUp(self):
261         self.tracking = []
262         self.obj = self.ContextTestObject()
263         self.handler = self.obj.connect('notify::prop', self.on_prop_set)
264
265     def test_freeze_notify_context(self):
266         # Verify prop tracking list
267         self.assertEqual(self.tracking, [])
268         self.obj.props.prop = 1
269         self.assertEqual(self.tracking, [1])
270         self.obj.props.prop = 2
271         self.assertEqual(self.tracking, [1, 2])
272         self.assertEqual(self.obj.__grefcount__, 1)
273
274         pyref_count = sys.getrefcount(self.obj)
275
276         # Using the context manager the tracking list should not be affected.
277         # The GObject reference count should stay the same and the python
278         # object ref-count should go up.
279         with self.obj.freeze_notify():
280             self.assertEqual(self.obj.__grefcount__, 1)
281             self.assertEqual(sys.getrefcount(self.obj), pyref_count + 1)
282             self.obj.props.prop = 3
283             self.assertEqual(self.obj.props.prop, 3)
284             self.assertEqual(self.tracking, [1, 2])
285
286         # After the context manager, the prop should have been modified,
287         # the tracking list will be modified, and the python object ref
288         # count goes back down.
289         gc.collect()
290         self.assertEqual(self.obj.props.prop, 3)
291         self.assertEqual(self.tracking, [1, 2, 3])
292         self.assertEqual(self.obj.__grefcount__, 1)
293         self.assertEqual(sys.getrefcount(self.obj), pyref_count)
294
295     def test_handler_block_context(self):
296         # Verify prop tracking list
297         self.assertEqual(self.tracking, [])
298         self.obj.props.prop = 1
299         self.assertEqual(self.tracking, [1])
300         self.obj.props.prop = 2
301         self.assertEqual(self.tracking, [1, 2])
302         self.assertEqual(self.obj.__grefcount__, 1)
303
304         pyref_count = sys.getrefcount(self.obj)
305
306         # Using the context manager the tracking list should not be affected.
307         # The GObject reference count should stay the same and the python
308         # object ref-count should go up.
309         with self.obj.handler_block(self.handler):
310             self.assertEqual(self.obj.__grefcount__, 1)
311             self.assertEqual(sys.getrefcount(self.obj), pyref_count + 1)
312             self.obj.props.prop = 3
313             self.assertEqual(self.obj.props.prop, 3)
314             self.assertEqual(self.tracking, [1, 2])
315
316         # After the context manager, the prop should have been modified
317         # the tracking list should have stayed the same and the GObject ref
318         # count goes back down.
319         gc.collect()
320         self.assertEqual(self.obj.props.prop, 3)
321         self.assertEqual(self.tracking, [1, 2])
322         self.assertEqual(self.obj.__grefcount__, 1)
323         self.assertEqual(sys.getrefcount(self.obj), pyref_count)
324
325     def test_freeze_notify_context_nested(self):
326         self.assertEqual(self.tracking, [])
327         with self.obj.freeze_notify():
328             self.obj.props.prop = 1
329             self.assertEqual(self.tracking, [])
330
331             with self.obj.freeze_notify():
332                 self.obj.props.prop = 2
333                 self.assertEqual(self.tracking, [])
334
335                 with self.obj.freeze_notify():
336                     self.obj.props.prop = 3
337                     self.assertEqual(self.tracking, [])
338                 self.assertEqual(self.tracking, [])
339             self.assertEqual(self.tracking, [])
340
341         # Finally after last context, the notifications should have collapsed
342         # and the last one sent.
343         self.assertEqual(self.tracking, [3])
344
345     def test_handler_block_context_nested(self):
346         self.assertEqual(self.tracking, [])
347         with self.obj.handler_block(self.handler):
348             self.obj.props.prop = 1
349             self.assertEqual(self.tracking, [])
350
351             with self.obj.handler_block(self.handler):
352                 self.obj.props.prop = 2
353                 self.assertEqual(self.tracking, [])
354
355                 with self.obj.handler_block(self.handler):
356                     self.obj.props.prop = 3
357                     self.assertEqual(self.tracking, [])
358                 self.assertEqual(self.tracking, [])
359             self.assertEqual(self.tracking, [])
360
361         # Finally after last context, the notifications should have collapsed
362         # and the last one sent.
363         self.assertEqual(self.obj.props.prop, 3)
364         self.assertEqual(self.tracking, [])
365
366     def test_freeze_notify_normal_usage_ref_counts(self):
367         # Ensure ref counts without using methods as context managers
368         # maintain the same count.
369         self.assertEqual(self.obj.__grefcount__, 1)
370         self.obj.freeze_notify()
371         self.assertEqual(self.obj.__grefcount__, 1)
372         self.obj.thaw_notify()
373         self.assertEqual(self.obj.__grefcount__, 1)
374
375     def test_handler_block_normal_usage_ref_counts(self):
376         self.assertEqual(self.obj.__grefcount__, 1)
377         self.obj.handler_block(self.handler)
378         self.assertEqual(self.obj.__grefcount__, 1)
379         self.obj.handler_unblock(self.handler)
380         self.assertEqual(self.obj.__grefcount__, 1)
381
382     def test_freeze_notify_context_error(self):
383         # Test an exception occurring within a freeze context exits the context
384         try:
385             with self.obj.freeze_notify():
386                 self.obj.props.prop = 1
387                 self.assertEqual(self.tracking, [])
388                 raise ValueError('Simulation')
389         except ValueError:
390             pass
391
392         # Verify the property set within the context called notify.
393         self.assertEqual(self.obj.props.prop, 1)
394         self.assertEqual(self.tracking, [1])
395
396         # Verify we are still not in a frozen context.
397         self.obj.props.prop = 2
398         self.assertEqual(self.tracking, [1, 2])
399
400     def test_handler_block_context_error(self):
401         # Test an exception occurring within a handler block exits the context
402         try:
403             with self.obj.handler_block(self.handler):
404                 self.obj.props.prop = 1
405                 self.assertEqual(self.tracking, [])
406                 raise ValueError('Simulation')
407         except ValueError:
408             pass
409
410         # Verify the property set within the context didn't call notify.
411         self.assertEqual(self.obj.props.prop, 1)
412         self.assertEqual(self.tracking, [])
413
414         # Verify we are still not in a handler block context.
415         self.obj.props.prop = 2
416         self.assertEqual(self.tracking, [2])
417
418
419 class TestPropertyBindings(unittest.TestCase):
420     class TestObject(GObject.GObject):
421         int_prop = GObject.Property(default=0, type=int)
422
423     def setUp(self):
424         self.source = self.TestObject()
425         self.target = self.TestObject()
426
427     def test_default_binding(self):
428         binding = self.source.bind_property('int_prop', self.target, 'int_prop',
429                                             GObject.BindingFlags.DEFAULT)
430         binding = binding  # PyFlakes
431
432         # Test setting value on source gets pushed to target
433         self.source.int_prop = 1
434         self.assertEqual(self.source.int_prop, 1)
435         self.assertEqual(self.target.int_prop, 1)
436
437         # Test setting value on target does not change source
438         self.target.props.int_prop = 2
439         self.assertEqual(self.source.int_prop, 1)
440         self.assertEqual(self.target.int_prop, 2)
441
442     def test_bidirectional_binding(self):
443         binding = self.source.bind_property('int_prop', self.target, 'int_prop',
444                                             GObject.BindingFlags.BIDIRECTIONAL)
445         binding = binding  # PyFlakes
446
447         # Test setting value on source gets pushed to target
448         self.source.int_prop = 1
449         self.assertEqual(self.source.int_prop, 1)
450         self.assertEqual(self.target.int_prop, 1)
451
452         # Test setting value on target also changes source
453         self.target.props.int_prop = 2
454         self.assertEqual(self.source.int_prop, 2)
455         self.assertEqual(self.target.int_prop, 2)
456
457     def test_transform_to_only(self):
458         def transform_to(binding, value, user_data=None):
459             self.assertEqual(user_data, 'test-data')
460             return value * 2
461
462         binding = self.source.bind_property('int_prop', self.target, 'int_prop',
463                                             GObject.BindingFlags.DEFAULT,
464                                             transform_to, None, 'test-data')
465         binding = binding  # PyFlakes
466
467         self.source.int_prop = 1
468         self.assertEqual(self.source.int_prop, 1)
469         self.assertEqual(self.target.int_prop, 2)
470
471         self.target.props.int_prop = 1
472         self.assertEqual(self.source.int_prop, 1)
473         self.assertEqual(self.target.int_prop, 1)
474
475     def test_transform_from_only(self):
476         def transform_from(binding, value, user_data=None):
477             self.assertEqual(user_data, None)
478             return value * 2
479
480         binding = self.source.bind_property('int_prop', self.target, 'int_prop',
481                                             GObject.BindingFlags.BIDIRECTIONAL,
482                                             None, transform_from)
483         binding = binding  # PyFlakes
484
485         self.source.int_prop = 1
486         self.assertEqual(self.source.int_prop, 1)
487         self.assertEqual(self.target.int_prop, 1)
488
489         self.target.props.int_prop = 1
490         self.assertEqual(self.source.int_prop, 2)
491         self.assertEqual(self.target.int_prop, 1)
492
493     def test_transform_bidirectional(self):
494         test_data = object()
495
496         def transform_to(binding, value, user_data=None):
497             self.assertEqual(user_data, test_data)
498             return value * 2
499
500         def transform_from(binding, value, user_data=None):
501             self.assertEqual(user_data, test_data)
502             return value // 2
503
504         test_data_ref_count = sys.getrefcount(test_data)
505         transform_to_ref_count = sys.getrefcount(transform_to)
506         transform_from_ref_count = sys.getrefcount(transform_from)
507
508         # bidirectional bindings
509         binding = self.source.bind_property('int_prop', self.target, 'int_prop',
510                                             GObject.BindingFlags.BIDIRECTIONAL,
511                                             transform_to, transform_from, test_data)
512         binding = binding  # PyFlakes
513         binding_ref_count = sys.getrefcount(binding())
514         binding_gref_count = binding().__grefcount__
515
516         self.source.int_prop = 1
517         self.assertEqual(self.source.int_prop, 1)
518         self.assertEqual(self.target.int_prop, 2)
519
520         self.target.props.int_prop = 4
521         self.assertEqual(self.source.int_prop, 2)
522         self.assertEqual(self.target.int_prop, 4)
523
524         self.assertEqual(sys.getrefcount(binding()), binding_ref_count)
525         self.assertEqual(binding().__grefcount__, binding_gref_count)
526
527         # test_data ref count increases by 2, once for each callback.
528         self.assertEqual(sys.getrefcount(test_data), test_data_ref_count + 2)
529         self.assertEqual(sys.getrefcount(transform_to), transform_to_ref_count + 1)
530         self.assertEqual(sys.getrefcount(transform_from), transform_from_ref_count + 1)
531
532         # Unbind should clear out the binding and its transforms
533         binding.unbind()
534         self.assertEqual(binding(), None)
535         del binding
536         gc.collect()
537
538         # Setting source or target should not change the other.
539         self.target.int_prop = 3
540         self.source.int_prop = 5
541         self.assertEqual(self.target.int_prop, 3)
542         self.assertEqual(self.source.int_prop, 5)
543
544         self.assertEqual(sys.getrefcount(test_data), test_data_ref_count)
545         self.assertEqual(sys.getrefcount(transform_to), transform_to_ref_count)
546         self.assertEqual(sys.getrefcount(transform_from), transform_from_ref_count)
547
548     def test_explicit_unbind_clears_connection(self):
549         self.assertEqual(self.source.int_prop, 0)
550         self.assertEqual(self.target.int_prop, 0)
551
552         # Test deleting binding reference removes binding.
553         binding = self.source.bind_property('int_prop', self.target, 'int_prop')
554         self.source.int_prop = 1
555         self.assertEqual(self.source.int_prop, 1)
556         self.assertEqual(self.target.int_prop, 1)
557
558         binding.unbind()
559         self.assertEqual(binding(), None)
560
561         self.source.int_prop = 10
562         self.assertEqual(self.source.int_prop, 10)
563         self.assertEqual(self.target.int_prop, 1)
564
565         # An already unbound BindingWeakRef will raise if unbind is attempted a second time.
566         self.assertRaises(ValueError, binding.unbind)
567
568     def test_reference_counts(self):
569         self.assertEqual(self.source.__grefcount__, 1)
570         self.assertEqual(self.target.__grefcount__, 1)
571
572         # Binding ref count will be 2 do to the initial ref implicitly held by
573         # the act of binding and the ref incurred by using __call__ to generate
574         # a wrapper from the weak binding ref within python.
575         binding = self.source.bind_property('int_prop', self.target, 'int_prop')
576         self.assertEqual(binding().__grefcount__, 2)
577
578         # Creating a binding does not inc refs on source and target (they are weak
579         # on the binding object itself)
580         self.assertEqual(self.source.__grefcount__, 1)
581         self.assertEqual(self.target.__grefcount__, 1)
582
583         # Use GObject.get_property because the "props" accessor leaks.
584         # Note property names are canonicalized.
585         self.assertEqual(binding().get_property('source'), self.source)
586         self.assertEqual(binding().get_property('source_property'), 'int-prop')
587         self.assertEqual(binding().get_property('target'), self.target)
588         self.assertEqual(binding().get_property('target_property'), 'int-prop')
589         self.assertEqual(binding().get_property('flags'), GObject.BindingFlags.DEFAULT)
590
591         # Delete reference to source or target and the binding should listen.
592         ref = self.source.weak_ref()
593         del self.source
594         gc.collect()
595         self.assertEqual(ref(), None)
596         self.assertEqual(binding(), None)
597
598
599 class TestGValue(unittest.TestCase):
600     def test_no_type(self):
601         value = GObject.Value()
602         self.assertEqual(value.g_type, GObject.TYPE_INVALID)
603         self.assertRaises(TypeError, value.set_value, 23)
604         self.assertEqual(value.get_value(), None)
605
606     def test_int(self):
607         value = GObject.Value(GObject.TYPE_UINT)
608         self.assertEqual(value.g_type, GObject.TYPE_UINT)
609         value.set_value(23)
610         self.assertEqual(value.get_value(), 23)
611         value.set_value(42.0)
612         self.assertEqual(value.get_value(), 42)
613
614     def test_string(self):
615         value = GObject.Value(str, 'foo_bar')
616         self.assertEqual(value.g_type, GObject.TYPE_STRING)
617         self.assertEqual(value.get_value(), 'foo_bar')
618
619     def test_float(self):
620         # python float is G_TYPE_DOUBLE
621         value = GObject.Value(float, 23.4)
622         self.assertEqual(value.g_type, GObject.TYPE_DOUBLE)
623
624         value = GObject.Value(GObject.TYPE_FLOAT, 23.4)
625         self.assertEqual(value.g_type, GObject.TYPE_FLOAT)
626         self.assertRaises(TypeError, value.set_value, 'string')
627
628     def test_enum(self):
629         value = GObject.Value(GLib.FileError, GLib.FileError.FAILED)
630         self.assertEqual(value.get_value(), GLib.FileError.FAILED)
631
632     def test_flags(self):
633         value = GObject.Value(GLib.IOFlags, GLib.IOFlags.IS_READABLE)
634         self.assertEqual(value.get_value(), GLib.IOFlags.IS_READABLE)
635
636     def test_object(self):
637         class TestObject(GObject.Object):
638             pass
639         obj = TestObject()
640         value = GObject.Value(GObject.TYPE_OBJECT, obj)
641         self.assertEqual(value.get_value(), obj)
642
643 if __name__ == '__main__':
644     unittest.main()