1 # -*- Mode: Python; py-indent-offset: 4 -*-
2 # vim: tabstop=4 shiftwidth=4 expandtab
8 from gi.repository import GLib
9 from compathelper import _long
12 class TestGVariant(unittest.TestCase):
13 def test_create_simple(self):
14 variant = GLib.Variant('i', 42)
15 self.assertTrue(isinstance(variant, GLib.Variant))
16 self.assertEqual(variant.get_int32(), 42)
18 variant = GLib.Variant('s', '')
19 self.assertTrue(isinstance(variant, GLib.Variant))
20 self.assertEqual(variant.get_string(), '')
22 variant = GLib.Variant('s', 'hello')
23 self.assertTrue(isinstance(variant, GLib.Variant))
24 self.assertEqual(variant.get_string(), 'hello')
26 def test_create_variant(self):
27 variant = GLib.Variant('v', GLib.Variant('i', 42))
28 self.assertTrue(isinstance(variant, GLib.Variant))
29 self.assertTrue(isinstance(variant.get_variant(), GLib.Variant))
30 self.assertEqual(variant.get_type_string(), 'v')
31 self.assertEqual(variant.get_variant().get_type_string(), 'i')
32 self.assertEqual(variant.get_variant().get_int32(), 42)
34 variant = GLib.Variant('v', GLib.Variant('v', GLib.Variant('i', 42)))
35 self.assertEqual(variant.get_type_string(), 'v')
36 self.assertEqual(variant.get_variant().get_type_string(), 'v')
37 self.assertEqual(variant.get_variant().get_variant().get_type_string(), 'i')
38 self.assertEqual(variant.get_variant().get_variant().get_int32(), 42)
40 def test_create_tuple(self):
41 variant = GLib.Variant('()', ())
42 self.assertEqual(variant.get_type_string(), '()')
43 self.assertEqual(variant.n_children(), 0)
45 variant = GLib.Variant('(i)', (3,))
46 self.assertEqual(variant.get_type_string(), '(i)')
47 self.assertTrue(isinstance(variant, GLib.Variant))
48 self.assertEqual(variant.n_children(), 1)
49 self.assertTrue(isinstance(variant.get_child_value(0), GLib.Variant))
50 self.assertEqual(variant.get_child_value(0).get_int32(), 3)
52 variant = GLib.Variant('(ss)', ('mec', 'mac'))
53 self.assertEqual(variant.get_type_string(), '(ss)')
54 self.assertTrue(isinstance(variant, GLib.Variant))
55 self.assertTrue(isinstance(variant.get_child_value(0), GLib.Variant))
56 self.assertTrue(isinstance(variant.get_child_value(1), GLib.Variant))
57 self.assertEqual(variant.get_child_value(0).get_string(), 'mec')
58 self.assertEqual(variant.get_child_value(1).get_string(), 'mac')
61 variant = GLib.Variant('((si)(ub))', (('hello', -1), (42, True)))
62 self.assertEqual(variant.get_type_string(), '((si)(ub))')
63 self.assertEqual(variant.unpack(), (('hello', -1), (_long(42), True)))
65 def test_new_tuple_sink(self):
66 # https://bugzilla.gnome.org/show_bug.cgi?id=735166
67 variant = GLib.Variant.new_tuple(GLib.Variant.new_tuple())
71 def test_create_dictionary(self):
72 variant = GLib.Variant('a{si}', {})
73 self.assertTrue(isinstance(variant, GLib.Variant))
74 self.assertEqual(variant.get_type_string(), 'a{si}')
75 self.assertEqual(variant.n_children(), 0)
77 variant = GLib.Variant('a{si}', {'': 1, 'key1': 2, 'key2': 3})
78 self.assertEqual(variant.get_type_string(), 'a{si}')
79 self.assertTrue(isinstance(variant, GLib.Variant))
80 self.assertTrue(isinstance(variant.get_child_value(0), GLib.Variant))
81 self.assertTrue(isinstance(variant.get_child_value(1), GLib.Variant))
82 self.assertTrue(isinstance(variant.get_child_value(2), GLib.Variant))
83 self.assertEqual(variant.unpack(), {'': 1, 'key1': 2, 'key2': 3})
86 variant = GLib.Variant('a{sa{si}}', {})
87 self.assertTrue(isinstance(variant, GLib.Variant))
88 self.assertEqual(variant.get_type_string(), 'a{sa{si}}')
89 self.assertEqual(variant.n_children(), 0)
91 d = {'': {'': 1, 'keyn1': 2},
92 'key1': {'key11': 11, 'key12': 12}}
93 variant = GLib.Variant('a{sa{si}}', d)
94 self.assertEqual(variant.get_type_string(), 'a{sa{si}}')
95 self.assertTrue(isinstance(variant, GLib.Variant))
96 self.assertEqual(variant.unpack(), d)
98 def test_create_array(self):
99 variant = GLib.Variant('ai', [])
100 self.assertEqual(variant.get_type_string(), 'ai')
101 self.assertEqual(variant.n_children(), 0)
103 variant = GLib.Variant('ai', [1, 2])
104 self.assertEqual(variant.get_type_string(), 'ai')
105 self.assertTrue(isinstance(variant, GLib.Variant))
106 self.assertTrue(isinstance(variant.get_child_value(0), GLib.Variant))
107 self.assertTrue(isinstance(variant.get_child_value(1), GLib.Variant))
108 self.assertEqual(variant.get_child_value(0).get_int32(), 1)
109 self.assertEqual(variant.get_child_value(1).get_int32(), 2)
111 variant = GLib.Variant('as', [])
112 self.assertEqual(variant.get_type_string(), 'as')
113 self.assertEqual(variant.n_children(), 0)
115 variant = GLib.Variant('as', [''])
116 self.assertEqual(variant.get_type_string(), 'as')
117 self.assertTrue(isinstance(variant, GLib.Variant))
118 self.assertTrue(isinstance(variant.get_child_value(0), GLib.Variant))
119 self.assertEqual(variant.get_child_value(0).get_string(), '')
121 variant = GLib.Variant('as', ['hello', 'world'])
122 self.assertEqual(variant.get_type_string(), 'as')
123 self.assertTrue(isinstance(variant, GLib.Variant))
124 self.assertTrue(isinstance(variant.get_child_value(0), GLib.Variant))
125 self.assertTrue(isinstance(variant.get_child_value(1), GLib.Variant))
126 self.assertEqual(variant.get_child_value(0).get_string(), 'hello')
127 self.assertEqual(variant.get_child_value(1).get_string(), 'world')
130 variant = GLib.Variant('aai', [])
131 self.assertEqual(variant.get_type_string(), 'aai')
132 self.assertEqual(variant.n_children(), 0)
134 variant = GLib.Variant('aai', [[]])
135 self.assertEqual(variant.get_type_string(), 'aai')
136 self.assertEqual(variant.n_children(), 1)
137 self.assertEqual(variant.get_child_value(0).n_children(), 0)
139 variant = GLib.Variant('aai', [[1, 2], [3, 4, 5]])
140 self.assertEqual(variant.get_type_string(), 'aai')
141 self.assertEqual(variant.unpack(), [[1, 2], [3, 4, 5]])
143 def test_create_complex(self):
144 variant = GLib.Variant('(as)', ([],))
145 self.assertEqual(variant.get_type_string(), '(as)')
146 self.assertEqual(variant.n_children(), 1)
147 self.assertEqual(variant.get_child_value(0).n_children(), 0)
149 variant = GLib.Variant('(as)', ([''],))
150 self.assertEqual(variant.get_type_string(), '(as)')
151 self.assertEqual(variant.n_children(), 1)
152 self.assertEqual(variant.get_child_value(0).n_children(), 1)
153 self.assertEqual(variant.get_child_value(0).get_child_value(0).get_string(), '')
155 variant = GLib.Variant('(as)', (['hello'],))
156 self.assertEqual(variant.get_type_string(), '(as)')
157 self.assertEqual(variant.n_children(), 1)
158 self.assertEqual(variant.get_child_value(0).n_children(), 1)
159 self.assertEqual(variant.get_child_value(0).get_child_value(0).get_string(), 'hello')
161 variant = GLib.Variant('a(ii)', [])
162 self.assertEqual(variant.get_type_string(), 'a(ii)')
163 self.assertEqual(variant.n_children(), 0)
165 variant = GLib.Variant('a(ii)', [(5, 6)])
166 self.assertEqual(variant.get_type_string(), 'a(ii)')
167 self.assertEqual(variant.n_children(), 1)
168 self.assertEqual(variant.get_child_value(0).n_children(), 2)
169 self.assertEqual(variant.get_child_value(0).get_child_value(0).get_int32(), 5)
170 self.assertEqual(variant.get_child_value(0).get_child_value(1).get_int32(), 6)
172 variant = GLib.Variant('(a(ii))', ([],))
173 self.assertEqual(variant.get_type_string(), '(a(ii))')
174 self.assertEqual(variant.n_children(), 1)
175 self.assertEqual(variant.get_child_value(0).n_children(), 0)
177 variant = GLib.Variant('(a(ii))', ([(5, 6)],))
178 self.assertEqual(variant.get_type_string(), '(a(ii))')
179 self.assertEqual(variant.n_children(), 1)
180 self.assertEqual(variant.get_child_value(0).n_children(), 1)
181 self.assertEqual(variant.get_child_value(0).get_child_value(0).n_children(), 2)
182 self.assertEqual(variant.get_child_value(0).get_child_value(0).get_child_value(0).get_int32(), 5)
183 self.assertEqual(variant.get_child_value(0).get_child_value(0).get_child_value(1).get_int32(), 6)
185 obj = {'a1': (1, True), 'a2': (2, False)}
186 variant = GLib.Variant('a{s(ib)}', obj)
187 self.assertEqual(variant.get_type_string(), 'a{s(ib)}')
188 self.assertEqual(variant.unpack(), obj)
190 obj = {'a1': (1, GLib.Variant('b', True)), 'a2': (2, GLib.Variant('y', 255))}
191 variant = GLib.Variant('a{s(iv)}', obj)
192 self.assertEqual(variant.get_type_string(), 'a{s(iv)}')
193 self.assertEqual(variant.unpack(), {'a1': (1, True), 'a2': (2, 255)})
195 obj = (1, {'a': {'a1': True, 'a2': False},
200 variant = GLib.Variant('(ia{sa{sb}}s)', obj)
201 self.assertEqual(variant.get_type_string(), '(ia{sa{sb}}s)')
202 self.assertEqual(variant.unpack(), obj)
204 obj = {"frequency": GLib.Variant('t', 738000000),
205 "hierarchy": GLib.Variant('i', 0),
206 "bandwidth": GLib.Variant('x', 8),
207 "code-rate-hp": GLib.Variant('d', 2.0 / 3.0),
208 "constellation": GLib.Variant('s', "QAM16"),
209 "guard-interval": GLib.Variant('u', 4)}
210 variant = GLib.Variant('a{sv}', obj)
211 self.assertEqual(variant.get_type_string(), 'a{sv}')
212 self.assertEqual(variant.unpack(),
213 {"frequency": 738000000,
216 "code-rate-hp": 2.0 / 3.0,
217 "constellation": "QAM16",
221 def test_create_errors(self):
223 self.assertRaises(TypeError, GLib.Variant, 'i', 42, 3)
224 self.assertRaises(TypeError, GLib.Variant, '(i)', (42, 3))
226 # not enough arguments
227 self.assertRaises(TypeError, GLib.Variant, '(ii)', (42,))
230 self.assertRaises(TypeError, GLib.Variant, 'i', 'hello')
231 self.assertRaises(TypeError, GLib.Variant, 's', 42)
232 self.assertRaises(TypeError, GLib.Variant, '(ss)', 'mec', 'mac')
233 self.assertRaises(TypeError, GLib.Variant, '(s)', 'hello')
235 # unimplemented data type
236 self.assertRaises(NotImplementedError, GLib.Variant, 'Q', 1)
239 self.assertRaises(TypeError, GLib.Variant, '(ii', (42, 3))
240 self.assertRaises(TypeError, GLib.Variant, '(ii))', (42, 3))
241 self.assertRaises(TypeError, GLib.Variant, 'a{si', {})
242 self.assertRaises(TypeError, GLib.Variant, 'a{si}}', {})
243 self.assertRaises(TypeError, GLib.Variant, 'a{iii}', {})
245 def test_unpack(self):
247 res = GLib.Variant.new_int32(-42).unpack()
248 self.assertEqual(res, -42)
250 res = GLib.Variant.new_uint64(34359738368).unpack()
251 self.assertEqual(res, 34359738368)
253 res = GLib.Variant.new_boolean(True).unpack()
254 self.assertEqual(res, True)
256 res = GLib.Variant.new_object_path('/foo/Bar').unpack()
257 self.assertEqual(res, '/foo/Bar')
260 res = GLib.Variant('v', GLib.Variant.new_int32(-42)).unpack()
261 self.assertEqual(res, -42)
263 GLib.Variant('v', GLib.Variant('v', GLib.Variant('i', 42)))
264 self.assertEqual(res, -42)
267 res = GLib.Variant.new_tuple(GLib.Variant.new_int32(-1),
268 GLib.Variant.new_string('hello')).unpack()
269 self.assertEqual(res, (-1, 'hello'))
272 vb = GLib.VariantBuilder.new(gi._gi.variant_type_from_string('ai'))
273 vb.add_value(GLib.Variant.new_int32(-1))
274 vb.add_value(GLib.Variant.new_int32(3))
275 res = vb.end().unpack()
276 self.assertEqual(res, [-1, 3])
279 res = GLib.Variant('a{si}', {'key1': 1, 'key2': 2}).unpack()
280 self.assertEqual(res, {'key1': 1, 'key2': 2})
283 v = GLib.Variant.new_maybe(GLib.VariantType.new('i'), GLib.Variant('i', 1))
285 self.assertEqual(res, 1)
286 v = GLib.Variant.new_maybe(GLib.VariantType.new('i'), None)
288 self.assertEqual(res, None)
290 def test_iteration(self):
292 vb = GLib.VariantBuilder.new(gi._gi.variant_type_from_string('ai'))
293 vb.add_value(GLib.Variant.new_int32(-1))
294 vb.add_value(GLib.Variant.new_int32(3))
297 self.assertEqual(len(v), 2)
298 self.assertEqual(v[0], -1)
299 self.assertEqual(v[1], 3)
300 self.assertEqual(v[-1], 3)
301 self.assertEqual(v[-2], -1)
302 self.assertRaises(IndexError, v.__getitem__, 2)
303 self.assertRaises(IndexError, v.__getitem__, -3)
304 self.assertRaises(ValueError, v.__getitem__, 'a')
307 self.assertEqual([x for x in v], [-1, 3])
308 self.assertEqual(list(v), [-1, 3])
311 v = GLib.Variant.new_tuple(GLib.Variant.new_int32(-1),
312 GLib.Variant.new_string('hello'))
313 self.assertEqual(len(v), 2)
314 self.assertEqual(v[0], -1)
315 self.assertEqual(v[1], 'hello')
316 self.assertEqual(v[-1], 'hello')
317 self.assertEqual(v[-2], -1)
318 self.assertRaises(IndexError, v.__getitem__, 2)
319 self.assertRaises(IndexError, v.__getitem__, -3)
320 self.assertRaises(ValueError, v.__getitem__, 'a')
323 self.assertEqual([x for x in v], [-1, 'hello'])
324 self.assertEqual(tuple(v), (-1, 'hello'))
326 # dictionary index access
327 vsi = GLib.Variant('a{si}', {'key1': 1, 'key2': 2})
328 vis = GLib.Variant('a{is}', {1: 'val1', 5: 'val2'})
330 self.assertEqual(len(vsi), 2)
331 self.assertEqual(vsi['key1'], 1)
332 self.assertEqual(vsi['key2'], 2)
333 self.assertRaises(KeyError, vsi.__getitem__, 'unknown')
335 self.assertEqual(len(vis), 2)
336 self.assertEqual(vis[1], 'val1')
337 self.assertEqual(vis[5], 'val2')
338 self.assertRaises(KeyError, vsi.__getitem__, 3)
340 # dictionary iteration
341 self.assertEqual(set(vsi.keys()), set(['key1', 'key2']))
342 self.assertEqual(set(vis.keys()), set([1, 5]))
344 # string index access
345 v = GLib.Variant('s', 'hello')
346 self.assertEqual(len(v), 5)
347 self.assertEqual(v[0], 'h')
348 self.assertEqual(v[4], 'o')
349 self.assertEqual(v[-1], 'o')
350 self.assertEqual(v[-5], 'h')
351 self.assertRaises(IndexError, v.__getitem__, 5)
352 self.assertRaises(IndexError, v.__getitem__, -6)
355 self.assertEqual([x for x in v], ['h', 'e', 'l', 'l', 'o'])
357 def test_split_signature(self):
358 self.assertEqual(GLib.Variant.split_signature('()'), [])
360 self.assertEqual(GLib.Variant.split_signature('s'), ['s'])
362 self.assertEqual(GLib.Variant.split_signature('as'), ['as'])
364 self.assertEqual(GLib.Variant.split_signature('(s)'), ['s'])
366 self.assertEqual(GLib.Variant.split_signature('(iso)'), ['i', 's', 'o'])
368 self.assertEqual(GLib.Variant.split_signature('(s(ss)i(ii))'),
369 ['s', '(ss)', 'i', '(ii)'])
371 self.assertEqual(GLib.Variant.split_signature('(as)'), ['as'])
373 self.assertEqual(GLib.Variant.split_signature('(s(ss)iaiaasa(ii))'),
374 ['s', '(ss)', 'i', 'ai', 'aas', 'a(ii)'])
376 self.assertEqual(GLib.Variant.split_signature('(a{iv}(ii)((ss)a{s(ss)}))'),
377 ['a{iv}', '(ii)', '((ss)a{s(ss)})'])
380 v1 = GLib.Variant('s', 'somestring')
381 v2 = GLib.Variant('s', 'somestring')
382 v3 = GLib.Variant('s', 'somestring2')
384 self.assertTrue(v2 in set([v1, v3]))
385 self.assertTrue(v2 in frozenset([v1, v3]))
386 self.assertTrue(v2 in {v1: '1', v3: '2'})
388 def test_compare(self):
389 # Check if identical GVariant are equal
391 def assert_equal(vtype, value):
392 self.assertEqual(GLib.Variant(vtype, value), GLib.Variant(vtype, value))
394 def assert_not_equal(vtype1, value1, vtype2, value2):
395 self.assertNotEqual(GLib.Variant(vtype1, value1), GLib.Variant(vtype2, value2))
397 numbers = ['y', 'n', 'q', 'i', 'u', 'x', 't', 'h', 'd']
399 assert_equal(num, 42)
400 assert_not_equal(num, 42, num, 41)
401 assert_not_equal(num, 42, 's', '42')
403 assert_equal('s', 'something')
404 assert_not_equal('s', 'something', 's', 'somethingelse')
405 assert_not_equal('s', 'something', 'i', 1234)
407 assert_equal('g', 'dustybinqhogx')
408 assert_not_equal('g', 'dustybinqhogx', 'g', 'dustybin')
409 assert_not_equal('g', 'dustybinqhogx', 'i', 1234)
411 assert_equal('o', '/dev/null')
412 assert_not_equal('o', '/dev/null', 'o', '/dev/zero')
413 assert_not_equal('o', '/dev/null', 'i', 1234)
415 assert_equal('(s)', ('strtuple',))
416 assert_not_equal('(s)', ('strtuple',), '(s)', ('strtuple2',))
418 assert_equal('a{si}', {'str': 42})
419 assert_not_equal('a{si}', {'str': 42}, 'a{si}', {'str': 43})
421 assert_equal('v', GLib.Variant('i', 42))
422 assert_not_equal('v', GLib.Variant('i', 42), 'v', GLib.Variant('i', 43))
425 # Check if the GVariant bool matches the unpacked Pythonic bool
427 def assert_equals_bool(vtype, value):
428 self.assertEqual(bool(GLib.Variant(vtype, value)), bool(value))
431 assert_equals_bool('b', True)
432 assert_equals_bool('b', False)
434 numbers = ['y', 'n', 'q', 'i', 'u', 'x', 't', 'h', 'd']
435 for number in numbers:
436 assert_equals_bool(number, 0)
437 assert_equals_bool(number, 1)
439 assert_equals_bool('s', '')
440 assert_equals_bool('g', '')
441 assert_equals_bool('s', 'something')
442 assert_equals_bool('o', '/dev/null')
443 assert_equals_bool('g', 'dustybinqhogx')
446 assert_equals_bool('ab', [True])
447 assert_equals_bool('ab', [False])
448 for number in numbers:
449 assert_equals_bool('a' + number, [])
450 assert_equals_bool('a' + number, [0])
451 assert_equals_bool('as', [])
452 assert_equals_bool('as', [''])
453 assert_equals_bool('ao', [])
454 assert_equals_bool('ao', ['/'])
455 assert_equals_bool('ag', [])
456 assert_equals_bool('ag', [''])
457 assert_equals_bool('aai', [[]])
460 assert_equals_bool('()', ())
461 for number in numbers:
462 assert_equals_bool('(' + number + ')', (0,))
463 assert_equals_bool('(s)', ('',))
464 assert_equals_bool('(o)', ('/',))
465 assert_equals_bool('(g)', ('',))
466 assert_equals_bool('(())', ((),))
469 assert_equals_bool('a{si}', {})
470 assert_equals_bool('a{si}', {'': 0})
472 # complex types, always True
473 assert_equals_bool('(as)', ([],))
474 assert_equals_bool('a{s(i)}', {'': (0,)})
476 # variant types, recursive unpacking
477 assert_equals_bool('v', GLib.Variant('i', 0))
478 assert_equals_bool('v', GLib.Variant('i', 1))
482 v = GLib.Variant.new_uint32(42)
483 self.assertEqual(repr(v), "GLib.Variant('u', 42)")
485 # with override constructor
486 v = GLib.Variant('(is)', (1, 'somestring'))
487 self.assertEqual(repr(v), "GLib.Variant('(is)', (1, 'somestring'))")
491 v = GLib.Variant.new_uint32(42)
492 self.assertEqual(str(v), 'uint32 42')
494 # with override constructor
495 v = GLib.Variant('(is)', (1, 'somestring'))
496 self.assertEqual(str(v), "(1, 'somestring')")
498 def test_parse_error(self):
499 # This test doubles as a test for GLib.Error marshaling.
501 with self.assertRaises(GLib.Error) as context:
502 GLib.Variant.parse(None, source_str, None, None)
503 e = context.exception
504 text = GLib.Variant.parse_error_print_context(e, source_str)
505 self.assertTrue(source_str in text)
507 def test_parse_error_exceptions(self):
509 self.assertRaisesRegexp(TypeError, 'Must be GLib.Error, not int',
510 GLib.Variant.parse_error_print_context,
513 gerror = GLib.Error(message=42) # not a string
514 self.assertRaisesRegexp(ValueError, ".*must have a 'message'.*",
515 GLib.Variant.parse_error_print_context,
518 gerror = GLib.Error(domain=42) # not a string
519 self.assertRaisesRegexp(ValueError, ".*must have a 'domain'.*",
520 GLib.Variant.parse_error_print_context,
523 gerror = GLib.Error(code='not an int')
524 self.assertRaisesRegexp(ValueError, ".*must have a 'code' int.*",
525 GLib.Variant.parse_error_print_context,
529 class TestConstants(unittest.TestCase):
531 def test_basic_types_limits(self):
532 self.assertTrue(isinstance(GLib.MINFLOAT, float))
533 self.assertTrue(isinstance(GLib.MAXLONG, (int, _long)))