forked from altdesktop/python-dbus-next
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
210 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
from typing import List | ||
from dbus_next import PropertyAccess, introspection as intr | ||
from dbus_next.service import method, signal, dbus_property, ServiceInterface | ||
|
||
from test.util import check_annotated, skip_reason_no_typing_annotated | ||
|
||
import pytest | ||
|
||
has_annotated = check_annotated() | ||
|
||
if has_annotated: | ||
from test.util import Annotated | ||
|
||
class ExampleInterface(ServiceInterface): | ||
def __init__(self): | ||
super().__init__('test.interface') | ||
self._some_prop = 55 | ||
self._another_prop = 101 | ||
self._weird_prop = 500 | ||
|
||
@method() | ||
def some_method(self, one: Annotated[str, 's'], two: Annotated[str, | ||
's']) -> Annotated[str, 's']: | ||
return 'hello' | ||
|
||
@method(name='renamed_method', disabled=True) | ||
def another_method(self, eight: Annotated[str, 'o'], six: Annotated[str, 't']): | ||
pass | ||
|
||
@signal() | ||
def some_signal(self) -> Annotated[List[str], 'as']: | ||
return ['result'] | ||
|
||
@signal(name='renamed_signal', disabled=True) | ||
def another_signal(self) -> Annotated[List, '(dodo)']: | ||
return [1, '/', 1, '/'] | ||
|
||
# an additional annotation is added to this one. PEP 593 says we shoould be | ||
# able to deal with that and only select the annotation that we understand | ||
@dbus_property(name='renamed_readonly_property', access=PropertyAccess.READ, disabled=True) | ||
def another_prop(self) -> Annotated[int, 42, 't']: | ||
return self._another_prop | ||
|
||
@dbus_property() | ||
def some_prop(self) -> Annotated[int, 'u']: | ||
return self._some_prop | ||
|
||
@some_prop.setter | ||
def some_prop(self, val: Annotated[int, 'u']): | ||
self._some_prop = val + 1 | ||
|
||
# for this one, the setter has a different name than the getter which is a | ||
# special case in the code | ||
@dbus_property() | ||
def weird_prop(self) -> Annotated[int, 't']: | ||
return self._weird_prop | ||
|
||
@weird_prop.setter | ||
def setter_for_weird_prop(self, val: Annotated[int, 't']): | ||
self._weird_prop = val | ||
|
||
|
||
@pytest.mark.skipif(not has_annotated, reason=skip_reason_no_typing_annotated) | ||
def test_method_decorator(): | ||
interface = ExampleInterface() | ||
assert interface.name == 'test.interface' | ||
|
||
properties = ServiceInterface._get_properties(interface) | ||
methods = ServiceInterface._get_methods(interface) | ||
signals = ServiceInterface._get_signals(interface) | ||
|
||
assert len(methods) == 2 | ||
|
||
method = methods[0] | ||
assert method.name == 'renamed_method' | ||
assert method.in_signature == 'ot' | ||
assert method.out_signature == '' | ||
assert method.disabled | ||
assert type(method.introspection) is intr.Method | ||
|
||
method = methods[1] | ||
assert method.name == 'some_method' | ||
assert method.in_signature == 'ss' | ||
assert method.out_signature == 's' | ||
assert not method.disabled | ||
assert type(method.introspection) is intr.Method | ||
|
||
assert len(signals) == 2 | ||
|
||
signal = signals[0] | ||
assert signal.name == 'renamed_signal' | ||
assert signal.signature == '(dodo)' | ||
assert signal.disabled | ||
assert type(signal.introspection) is intr.Signal | ||
|
||
signal = signals[1] | ||
assert signal.name == 'some_signal' | ||
assert signal.signature == 'as' | ||
assert not signal.disabled | ||
assert type(signal.introspection) is intr.Signal | ||
|
||
assert len(properties) == 3 | ||
|
||
renamed_readonly_prop = properties[0] | ||
assert renamed_readonly_prop.name == 'renamed_readonly_property' | ||
assert renamed_readonly_prop.signature == 't' | ||
assert renamed_readonly_prop.access == PropertyAccess.READ | ||
assert renamed_readonly_prop.disabled | ||
assert type(renamed_readonly_prop.introspection) is intr.Property | ||
|
||
weird_prop = properties[1] | ||
assert weird_prop.name == 'weird_prop' | ||
assert weird_prop.access == PropertyAccess.READWRITE | ||
assert weird_prop.signature == 't' | ||
assert not weird_prop.disabled | ||
assert weird_prop.prop_getter is not None | ||
assert weird_prop.prop_getter.__name__ == 'weird_prop' | ||
assert weird_prop.prop_setter is not None | ||
assert weird_prop.prop_setter.__name__ == 'setter_for_weird_prop' | ||
assert type(weird_prop.introspection) is intr.Property | ||
|
||
prop = properties[2] | ||
assert prop.name == 'some_prop' | ||
assert prop.access == PropertyAccess.READWRITE | ||
assert prop.signature == 'u' | ||
assert not prop.disabled | ||
assert prop.prop_getter is not None | ||
assert prop.prop_setter is not None | ||
assert type(prop.introspection) is intr.Property | ||
|
||
# make sure the getter and setter actually work | ||
assert interface._some_prop == 55 | ||
interface._some_prop = 555 | ||
assert interface.some_prop == 555 | ||
|
||
assert interface._weird_prop == 500 | ||
assert weird_prop.prop_getter(interface) == 500 | ||
interface._weird_prop = 1001 | ||
assert interface._weird_prop == 1001 | ||
weird_prop.prop_setter(interface, 600) | ||
assert interface._weird_prop == 600 | ||
|
||
|
||
@pytest.mark.skipif(not has_annotated, reason=skip_reason_no_typing_annotated) | ||
def test_interface_introspection(): | ||
interface = ExampleInterface() | ||
intr_interface = interface.introspect() | ||
assert type(intr_interface) is intr.Interface | ||
|
||
xml = intr_interface.to_xml() | ||
|
||
assert xml.tag == 'interface' | ||
assert xml.attrib.get('name', None) == 'test.interface' | ||
|
||
methods = xml.findall('method') | ||
signals = xml.findall('signal') | ||
properties = xml.findall('property') | ||
|
||
assert len(xml) == 4 | ||
assert len(methods) == 1 | ||
assert len(signals) == 1 | ||
assert len(properties) == 2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters