1# Copyright 2012 Christoph Reiter <reiter.christoph@gmail.com>
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7
8from tests import TestCase, skipUnless
9
10try:
11    import dbus
12except ImportError:
13    dbus = None
14else:
15    from quodlibet.util.dbusutils import apply_signature, list_spec_properties
16    from quodlibet.util.dbusutils import filter_property_spec, DBusProperty
17    from quodlibet.util.dbusutils import dbus_unicode_validate
18
19
20ANN1 = """
21<property name="Position" type="s" access="read">
22<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" \
23value="false"/>
24</property>
25<property name="MinimumRate" type="s" access="read"/>
26"""
27
28ANN2 = """
29<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" \
30value="false"/>
31<property name="Foobar" type="s" access="read">
32<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" \
33value="invalidates"/>
34</property>
35<property name="XXX" type="s" access="read"/>
36"""
37
38
39@skipUnless(dbus, "dbus missing")
40class TDbusUtils(TestCase):
41
42    def test_prop_sig(self):
43        value = apply_signature(2, "u")
44        self.failUnless(isinstance(value, dbus.UInt32))
45
46        value = apply_signature({"a": "b"}, "a{ss}")
47        self.failUnlessEqual(value.signature, "ss")
48        self.failUnless(isinstance(value, dbus.Dictionary))
49
50        value = apply_signature(("a",), "a(s)")
51        self.failUnlessEqual(value.signature, "s")
52        self.failUnless(isinstance(value, dbus.Struct))
53
54        value = apply_signature(("a", "b"), "as")
55        self.failUnlessEqual(value.signature, "s")
56        self.failUnless(isinstance(value, dbus.Array))
57
58        self.failUnlessRaises(TypeError, apply_signature, 2, "a(s)")
59
60        text = b'\xc3\xb6\xc3\xa4\xc3\xbc'
61        value = apply_signature(text, "s", utf8_strings=True)
62        self.failUnless(isinstance(value, str))
63        value = apply_signature(text, "s")
64        self.failUnless(isinstance(value, str))
65
66        text = u"öäü"
67        value = apply_signature(text, "s", utf8_strings=True)
68        self.failUnless(isinstance(value, str))
69        value = apply_signature(text, "s")
70        self.failUnless(isinstance(value, str))
71
72    def test_list_props(self):
73        props = list_spec_properties(ANN1)
74        self.failUnlessEqual(props["Position"]["access"], "read")
75        self.failUnlessEqual(props["Position"]["emit"], "false")
76        self.failUnlessEqual(props["Position"]["type"], "s")
77
78        self.failUnlessEqual(props["MinimumRate"]["emit"], "true")
79
80        props = list_spec_properties(ANN2)
81        self.failUnlessEqual(props["Foobar"]["emit"], "invalidates")
82        self.failUnlessEqual(props["XXX"]["emit"], "false")
83
84    def test_filter_props(self):
85        spec = filter_property_spec(ANN1, wl=["Position"])
86        self.failUnlessEqual(
87            list(list_spec_properties(spec).keys()), ["Position"])
88        props = list_spec_properties(spec)
89        self.failUnlessEqual(props["Position"]["emit"], "false")
90
91        spec = filter_property_spec(ANN1, bl=["Position"])
92        self.failUnlessEqual(list(list_spec_properties(spec).keys()),
93                             ["MinimumRate"])
94
95        spec = filter_property_spec(ANN1)
96        self.failUnlessEqual(len(list_spec_properties(spec).keys()), 2)
97
98    def test_validate_utf8(self):
99        self.failUnlessEqual(dbus_unicode_validate(u'X\ufffeX'), u"X\ufffdX")
100        self.failUnlessEqual(dbus_unicode_validate(b'X\xef\xbf\xbeX'),
101                             u"X\ufffdX")
102
103    def test_property_mixin(self):
104
105        class X(DBusProperty):
106            SUPPORTS_MULTIPLE_OBJECT_PATHS = False
107
108            def set_introspection(self, *args):
109                pass
110
111            def get_property(self, interface, name):
112                return interface
113
114            def set_property(self, interface, name, value):
115                pass
116
117        x = X()
118        x.set_properties("a1", ANN1)
119        x.set_properties("a2", ANN2)
120        x.implement_interface("a1", "a2")
121
122        props = x.get_properties("a1")
123        self.failUnless(("a1", "Position") in props)
124        self.failUnless(("a2", "XXX") in props)
125        props = x.get_properties("a2")
126        self.failIf(("a1", "Position") in props)
127
128        self.failUnlessEqual(x.get_interface("a2", "XXX"), "a2")
129        self.failUnlessEqual(x.get_interface("a1", "XXX"), "a2")
130
131        self.failUnlessEqual(x.get_value("a2", "XXX"), "a2")
132        self.failUnlessEqual(x.get_value("a1", "XXX"), "a2")
133        self.failUnlessEqual(x.get_value("a1", "Position"), "a1")
134