Branched from 2.0alpha and pushed for 2.0
[profile/ivi/dbus-python.git] / test / test-standalone.py
1 #!/usr/bin/env python
2
3 """Tests that don't need an active D-Bus connection to run, but can be
4 run in isolation.
5 """
6
7 # Copyright (C) 2006 Collabora Ltd. <http://www.collabora.co.uk/>
8 #
9 # Permission is hereby granted, free of charge, to any person
10 # obtaining a copy of this software and associated documentation
11 # files (the "Software"), to deal in the Software without
12 # restriction, including without limitation the rights to use, copy,
13 # modify, merge, publish, distribute, sublicense, and/or sell copies
14 # of the Software, and to permit persons to whom the Software is
15 # furnished to do so, subject to the following conditions:
16 #
17 # The above copyright notice and this permission notice shall be
18 # included in all copies or substantial portions of the Software.
19 #
20 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 # DEALINGS IN THE SOFTWARE.
28
29 import sys
30 import os
31 import unittest
32 import time
33 from traceback import print_exc
34
35 builddir = os.path.normpath(os.environ["DBUS_TOP_BUILDDIR"])
36 pydir = os.path.normpath(os.environ["DBUS_TOP_SRCDIR"])
37
38 import _dbus_bindings
39 import dbus
40 import dbus.types as types
41
42 # Check that we're using the right versions
43 if not dbus.__file__.startswith(pydir):
44     raise Exception("DBus modules (%s) are not being picked up from the package"%dbus.__file__)
45 if not _dbus_bindings.__file__.startswith(builddir):
46     raise Exception("DBus modules (%s) are not being picked up from the package"%_dbus_bindings.__file__)
47 assert (_dbus_bindings._python_version & 0xffff0000
48         == sys.hexversion & 0xffff0000), \
49         '_dbus_bindings was compiled for Python %x but this is Python %x, '\
50         'a different major version'\
51         % (_dbus_bindings._python_version, sys.hexversion)
52 assert _dbus_bindings.__version__ == os.environ['DBUS_PYTHON_VERSION'], \
53         '_dbus_bindings was compiled as version %s but Automake says '\
54         'we should be version %s' \
55         % (_dbus_bindings.__version__, os.environ['DBUS_PYTHON_VERSION'])
56
57 class TestTypes(unittest.TestCase):
58
59     def test_Dictionary(self):
60         self.assertEquals(types.Dictionary({'foo':'bar'}), {'foo':'bar'})
61         self.assertEquals(types.Dictionary({}, variant_level=2), {})
62         self.assertEquals(types.Dictionary({}, variant_level=2).variant_level, 2)
63
64     def test_Array(self):
65         self.assertEquals(types.Array(['foo','bar']), ['foo','bar'])
66         self.assertEquals(types.Array([], variant_level=2), [])
67         self.assertEquals(types.Array([], variant_level=2).variant_level, 2)
68
69     def test_Double(self):
70         self.assertEquals(types.Double(0.0), 0.0)
71         self.assertEquals(types.Double(0.125, variant_level=2), 0.125)
72         self.assertEquals(types.Double(0.125, variant_level=2).variant_level, 2)
73
74     def test_Struct(self):
75         x = types.Struct(('',))
76         self.assertEquals(x.variant_level, 0)
77         self.assertEquals(x, ('',))
78         x = types.Struct('abc', variant_level=42)
79         self.assertEquals(x.variant_level, 42)
80         self.assertEquals(x, ('a','b','c'))
81
82     def test_Byte(self):
83         self.assertEquals(types.Byte('x', variant_level=2), types.Byte(ord('x')))
84
85     def test_object_path_attr(self):
86         class MyObject(object):
87             __dbus_object_path__ = '/foo'
88         from _dbus_bindings import SignalMessage
89         self.assertEquals(SignalMessage.guess_signature(MyObject()), 'o')
90
91     def test_integers(self):
92         # This is an API guarantee. Note that exactly which of these types
93         # are ints and which of them are longs is *not* guaranteed.
94         for cls in (types.Int16, types.UInt16, types.Int32, types.UInt32,
95             types.Int64, types.UInt64):
96             self.assert_(issubclass(cls, (int, long)))
97             self.assert_(isinstance(cls(0), (int, long)))
98             self.assertEquals(cls(0), 0)
99             self.assertEquals(cls(23, variant_level=1), 23)
100             self.assertEquals(cls(23, variant_level=1).variant_level, 1)
101
102     def test_integer_limits_16(self):
103         self.assertEquals(types.Int16(0x7fff), 0x7fff)
104         self.assertEquals(types.Int16(-0x8000), -0x8000)
105         self.assertEquals(types.UInt16(0xffff), 0xffff)
106         self.assertRaises(Exception, types.Int16, 0x8000)
107         self.assertRaises(Exception, types.Int16, -0x8001)
108         self.assertRaises(Exception, types.UInt16, 0x10000)
109
110     def test_integer_limits_32(self):
111         self.assertEquals(types.Int32(0x7fffffff), 0x7fffffff)
112         self.assertEquals(types.Int32(-0x80000000L), -0x80000000L)
113         self.assertEquals(types.UInt32(0xffffffffL), 0xffffffffL)
114         self.assertRaises(Exception, types.Int32, 0x80000000L)
115         self.assertRaises(Exception, types.Int32, -0x80000001L)
116         self.assertRaises(Exception, types.UInt32, 0x100000000L)
117
118     def test_integer_limits_64(self):
119         self.assertEquals(types.Int64(0x7fffffffffffffffL), 0x7fffffffffffffffL)
120         self.assertEquals(types.Int64(-0x8000000000000000L), -0x8000000000000000L)
121         self.assertEquals(types.UInt64(0xffffffffffffffffL), 0xffffffffffffffffL)
122         self.assertRaises(Exception, types.Int16, 0x8000000000000000L)
123         self.assertRaises(Exception, types.Int16, -0x8000000000000001L)
124         self.assertRaises(Exception, types.UInt16, 0x10000000000000000L)
125
126     def test_Signature(self):
127         self.assertRaises(Exception, types.Signature, 'a')
128         self.assertEquals(types.Signature('ab', variant_level=23), 'ab')
129         self.assert_(isinstance(types.Signature('ab'), str))
130         self.assertEquals(tuple(types.Signature('ab(xt)a{sv}')),
131                           ('ab', '(xt)', 'a{sv}'))
132         self.assert_(isinstance(tuple(types.Signature('ab'))[0],
133                                 types.Signature))
134
135
136 class TestMessageMarshalling(unittest.TestCase):
137
138     def test_count(self):
139         from _dbus_bindings import SignalMessage
140         s = SignalMessage('/', 'foo.bar', 'baz')
141         try:
142             s.append('a', signature='ss')
143         except TypeError:
144             pass
145         else:
146             raise AssertionError('Appending too few things in a message '
147                                  'should fail')
148         s = SignalMessage('/', 'foo.bar', 'baz')
149         try:
150             s.append('a','b','c', signature='ss')
151         except TypeError:
152             pass
153         else:
154             raise AssertionError('Appending too many things in a message '
155                                  'should fail')
156
157     def test_append(self):
158         aeq = self.assertEquals
159         from _dbus_bindings import SignalMessage
160         s = SignalMessage('/', 'foo.bar', 'baz')
161         s.append([types.Byte(1)], signature='ay')
162         aeq(s.get_signature(), 'ay')
163         aeq(s.get_args_list(), [[types.Byte(1)]])
164
165         s = SignalMessage('/', 'foo.bar', 'baz')
166         s.append([], signature='ay')
167         aeq(s.get_args_list(), [[]])
168
169     def test_append_ByteArray(self):
170         aeq = self.assertEquals
171         from _dbus_bindings import SignalMessage
172         s = SignalMessage('/', 'foo.bar', 'baz')
173         s.append(types.ByteArray('ab'), signature='ay')
174         aeq(s.get_args_list(), [[types.Byte('a'), types.Byte('b')]])
175         s = SignalMessage('/', 'foo.bar', 'baz')
176         s.append(types.ByteArray('ab'), signature='av')
177         aeq(s.get_args_list(), [[types.Byte('a'), types.Byte('b')]])
178
179     def test_append_Variant(self):
180         a = self.assert_
181         aeq = self.assertEquals
182         from _dbus_bindings import SignalMessage
183         s = SignalMessage('/', 'foo.bar', 'baz')
184         s.append(types.Int32(1, variant_level=0),
185                  types.String('a', variant_level=42),
186                  types.Array([types.Byte('a', variant_level=1),
187                               types.UInt32(123, variant_level=1)],
188                              signature='v'),
189                  signature='vvv')
190         aeq(s.get_signature(), 'vvv')
191         args = s.get_args_list()
192         aeq(args[0].__class__, types.Int32)
193         aeq(args[0].variant_level, 1)
194         aeq(args[1].__class__, types.String)
195         aeq(args[1].variant_level, 42)
196         aeq(args[2].__class__, types.Array)
197         aeq(args[2].variant_level, 1)
198         aeq(args[2].signature, 'v')
199
200     def test_guess_signature(self):
201         aeq = self.assertEquals
202         from _dbus_bindings import Message
203         aeq(Message.guess_signature(('a','b')), '(ss)')
204         aeq(Message.guess_signature('a','b'), 'ss')
205         aeq(Message.guess_signature(['a','b']), 'as')
206         aeq(Message.guess_signature(('a',)), '(s)')
207         aeq(Message.guess_signature('abc'), 's')
208         aeq(Message.guess_signature(types.Int32(123)), 'i')
209         aeq(Message.guess_signature(types.ByteArray('abc')), 'ay')
210         aeq(Message.guess_signature(('a',)), '(s)')
211         aeq(Message.guess_signature(['a']), 'as')
212         aeq(Message.guess_signature({'a':'b'}), 'a{ss}')
213
214     def test_guess_signature_dbus_types(self):
215         aeq = self.assertEquals
216         from _dbus_bindings import Message
217         gs = Message.guess_signature
218         aeq(gs(types.Dictionary({'a':'b'})), 'a{ss}')
219         aeq(gs(types.Dictionary({'a':'b'}, signature='sv')), 'a{sv}')
220         aeq(gs(types.Dictionary({}, signature='iu')), 'a{iu}')
221         aeq(gs(types.Array([types.Int32(1)])), 'ai')
222         aeq(gs(types.Array([types.Int32(1)], signature='u')), 'au')
223
224     def test_get_args_options(self):
225         aeq = self.assertEquals
226         s = _dbus_bindings.SignalMessage('/', 'foo.bar', 'baz')
227         s.append('b', 'bytes', -1, 1, 'str', 'var', signature='yayiusv')
228         aeq(s.get_args_list(), [ord('b'),
229                                 [ord('b'),ord('y'),ord('t'),ord('e'), ord('s')],
230                                 -1, 1, u'str', u'var'])
231         byte, bytes, int32, uint32, string, variant = s.get_args_list()
232         aeq(byte.__class__, types.Byte)
233         aeq(bytes.__class__, types.Array)
234         aeq(bytes[0].__class__, types.Byte)
235         aeq(int32.__class__, types.Int32)
236         aeq(uint32.__class__, types.UInt32)
237         aeq(string.__class__, types.String)
238         aeq(string.variant_level, 0)
239         aeq(variant.__class__, types.String)
240         aeq(variant.variant_level, 1)
241
242         byte, bytes, int32, uint32, string, variant = s.get_args_list(
243                 byte_arrays=True)
244         aeq(byte.__class__, types.Byte)
245         aeq(bytes.__class__, types.ByteArray)
246         aeq(bytes, 'bytes')
247         aeq(bytes[0].__class__, str)
248         aeq(int32.__class__, types.Int32)
249         aeq(uint32.__class__, types.UInt32)
250         aeq(string.__class__, types.String)
251         aeq(variant.__class__, types.String)
252         aeq(variant.variant_level, 1)
253
254         byte, bytes, int32, uint32, string, variant = s.get_args_list(
255             utf8_strings=True)
256         aeq(byte.__class__, types.Byte)
257         aeq(bytes.__class__, types.Array)
258         aeq(bytes[0].__class__, types.Byte)
259         aeq(int32.__class__, types.Int32)
260         aeq(uint32.__class__, types.UInt32)
261         aeq(string.__class__, types.UTF8String)
262         aeq(string, 'str')
263         aeq(variant.__class__, types.UTF8String)
264         aeq(variant.variant_level, 1)
265         aeq(variant, 'var')
266
267     def test_object_path_attr(self):
268         from _dbus_bindings import SignalMessage
269         class MyObject(object):
270             __dbus_object_path__ = '/foo'
271         s = SignalMessage('/', 'foo.bar', 'baz')
272         s.append(MyObject(), signature='o')
273         s.append(MyObject())
274         self.assertEquals(s.get_args_list(), ['/foo', '/foo'])
275
276     def test_struct(self):
277         from _dbus_bindings import SignalMessage
278         s = SignalMessage('/', 'foo.bar', 'baz')
279         try:
280             s.append(('a',), signature='(ss)')
281         except TypeError:
282             pass
283         else:
284             raise AssertionError('Appending too few things in a struct '
285                                  'should fail')
286         s = SignalMessage('/', 'foo.bar', 'baz')
287         try:
288             s.append(('a','b','c'), signature='(ss)')
289         except TypeError:
290             pass
291         else:
292             raise AssertionError('Appending too many things in a struct '
293                                  'should fail')
294
295
296 if __name__ == '__main__':
297     unittest.main()