mirror of
https://github.com/tiqi-group/pydase.git
synced 2025-04-19 16:10:01 +02:00

When collecting collection item property dependencies, the PropertyObserver was adding dict keys in single quotes instead of double quotes.
187 lines
5.5 KiB
Python
187 lines
5.5 KiB
Python
import logging
|
|
from typing import Any
|
|
|
|
import pydase
|
|
import pytest
|
|
from pydase.data_service.data_service_observer import DataServiceObserver
|
|
from pydase.data_service.state_manager import StateManager
|
|
from pydase.utils.serialization.serializer import SerializationError, dump
|
|
|
|
logger = logging.getLogger()
|
|
|
|
|
|
def test_static_property_dependencies() -> None:
|
|
class SubClass(pydase.DataService):
|
|
_name = "SubClass"
|
|
|
|
@property
|
|
def name(self) -> str:
|
|
return self._name
|
|
|
|
@name.setter
|
|
def name(self, value: str) -> None:
|
|
self._name = value
|
|
|
|
class ServiceClass(pydase.DataService):
|
|
def __init__(self) -> None:
|
|
super().__init__()
|
|
self.list_attr = [SubClass()]
|
|
self._name = "ServiceClass"
|
|
|
|
@property
|
|
def name(self) -> str:
|
|
return self._name
|
|
|
|
@name.setter
|
|
def name(self, value: str) -> None:
|
|
self._name = value
|
|
|
|
service_instance = ServiceClass()
|
|
state_manager = StateManager(service_instance)
|
|
observer = DataServiceObserver(state_manager)
|
|
logger.debug(observer.property_deps_dict)
|
|
assert observer.property_deps_dict == {
|
|
"list_attr[0]._name": ["list_attr[0].name"],
|
|
"_name": ["name"],
|
|
}
|
|
|
|
|
|
def test_dynamic_list_property_dependencies() -> None:
|
|
class SubClass(pydase.DataService):
|
|
_name = "SubClass"
|
|
|
|
@property
|
|
def name(self) -> str:
|
|
return self._name
|
|
|
|
@name.setter
|
|
def name(self, value: str) -> None:
|
|
self._name = value
|
|
|
|
class ServiceClass(pydase.DataService):
|
|
def __init__(self) -> None:
|
|
super().__init__()
|
|
self.list_attr = [SubClass()]
|
|
|
|
service_instance = ServiceClass()
|
|
state_manager = StateManager(service_instance)
|
|
observer = DataServiceObserver(state_manager)
|
|
|
|
assert observer.property_deps_dict == {
|
|
"list_attr[0]._name": ["list_attr[0].name"],
|
|
}
|
|
|
|
service_instance.list_attr.append(SubClass())
|
|
|
|
assert observer.property_deps_dict == {
|
|
"list_attr[0]._name": ["list_attr[0].name"],
|
|
"list_attr[1]._name": ["list_attr[1].name"],
|
|
}
|
|
|
|
|
|
def test_protected_or_private_change_logs(caplog: pytest.LogCaptureFixture) -> None:
|
|
class OtherService(pydase.DataService):
|
|
def __init__(self) -> None:
|
|
super().__init__()
|
|
self._name = "Hi"
|
|
|
|
class MyService(pydase.DataService):
|
|
def __init__(self) -> None:
|
|
super().__init__()
|
|
self.subclass = OtherService()
|
|
|
|
service = MyService()
|
|
state_manager = StateManager(service)
|
|
DataServiceObserver(state_manager)
|
|
|
|
service.subclass._name = "Hello"
|
|
assert "'subclass._name' changed to 'Hello'" not in caplog.text
|
|
|
|
|
|
def test_dynamic_list_entry_with_property(caplog: pytest.LogCaptureFixture) -> None:
|
|
class PropertyClass(pydase.DataService):
|
|
_name = "Hello"
|
|
|
|
@property
|
|
def name(self) -> str:
|
|
"""The name property."""
|
|
return self._name
|
|
|
|
class MyService(pydase.DataService):
|
|
def __init__(self) -> None:
|
|
super().__init__()
|
|
self.list_attr = []
|
|
|
|
def toggle_high_voltage(self) -> None:
|
|
self.list_attr = []
|
|
self.list_attr.append(PropertyClass())
|
|
self.list_attr[0]._name = "Hoooo"
|
|
|
|
service = MyService()
|
|
state_manager = StateManager(service)
|
|
DataServiceObserver(state_manager)
|
|
service.toggle_high_voltage()
|
|
|
|
assert "'list_attr[0].name' changed to 'Hello'" not in caplog.text
|
|
assert "'list_attr[0].name' changed to 'Hoooo'" in caplog.text
|
|
|
|
|
|
def test_private_attribute_does_not_have_to_be_serializable() -> None:
|
|
class MyService(pydase.DataService):
|
|
def __init__(self) -> None:
|
|
super().__init__()
|
|
self.publ_attr: Any = 1
|
|
self.__priv_attr = (1,)
|
|
|
|
def change_publ_attr(self) -> None:
|
|
self.publ_attr = (2,) # cannot be serialized
|
|
|
|
def change_priv_attr(self) -> None:
|
|
self.__priv_attr = (2,)
|
|
|
|
service_instance = MyService()
|
|
pydase.Server(service_instance)
|
|
|
|
with pytest.raises(SerializationError):
|
|
service_instance.change_publ_attr()
|
|
|
|
service_instance.change_priv_attr()
|
|
|
|
|
|
def test_normalized_attr_path_in_dependent_property_changes(
|
|
caplog: pytest.LogCaptureFixture,
|
|
) -> None:
|
|
class SubService(pydase.DataService):
|
|
_prop = 10.0
|
|
|
|
@property
|
|
def prop(self) -> float:
|
|
return self._prop
|
|
|
|
class MyService(pydase.DataService):
|
|
def __init__(self) -> None:
|
|
super().__init__()
|
|
self.service_dict = {"one": SubService()}
|
|
|
|
service_instance = MyService()
|
|
state_manager = StateManager(service=service_instance)
|
|
observer = DataServiceObserver(state_manager=state_manager)
|
|
|
|
assert observer.property_deps_dict['service_dict["one"]._prop'] == [
|
|
'service_dict["one"].prop'
|
|
]
|
|
|
|
# We can use dict key path encoded with double quotes
|
|
state_manager.set_service_attribute_value_by_path(
|
|
'service_dict["one"]._prop', dump(11.0)
|
|
)
|
|
assert service_instance.service_dict["one"].prop == 11.0
|
|
assert "'service_dict[\"one\"].prop' changed to '11.0'" in caplog.text
|
|
|
|
# We can use dict key path encoded with single quotes
|
|
state_manager.set_service_attribute_value_by_path(
|
|
"service_dict['one']._prop", dump(12.0)
|
|
)
|
|
assert service_instance.service_dict["one"].prop == 12.0
|
|
assert "'service_dict[\"one\"].prop' changed to '12.0'" in caplog.text
|