from typing import Any import pydase import pydase.units as u from pydase.data_service.data_service import DataService from pydase.data_service.data_service_observer import DataServiceObserver from pydase.data_service.state_manager import StateManager, load_state from pydase.utils.serialization.serializer import dump from pytest import LogCaptureFixture def test_DataService_setattr(caplog: LogCaptureFixture) -> None: class ServiceClass(DataService): voltage = 1.0 * u.units.V _current: u.Quantity = 1.0 * u.units.mA @property def current(self) -> u.Quantity: return self._current @current.setter def current(self, value: Any) -> None: self._current = value service_instance = ServiceClass() state_manager = StateManager(service_instance) DataServiceObserver(state_manager) service_instance.voltage = 10.0 * u.units.V service_instance.current = 1.5 * u.units.mA assert "'voltage' changed to '10.0 V'" in caplog.text assert "'current' changed to '1.5 mA'" in caplog.text assert service_instance.voltage == 10.0 * u.units.V assert service_instance.current == 1.5 * u.units.mA caplog.clear() service_instance.voltage = 12.0 * u.units.V service_instance.current = 1.51 * u.units.A assert "'voltage' changed to '12.0 V'" in caplog.text assert "'current' changed to '1.51 A'" in caplog.text assert service_instance.voltage == 12.0 * u.units.V assert service_instance.current == 1.51 * u.units.A def test_convert_to_quantity() -> None: assert u.convert_to_quantity(1.0, unit="V") == 1.0 * u.units.V assert u.convert_to_quantity(1, unit="mV") == 1.0 * u.units.mV assert u.convert_to_quantity({"magnitude": 12, "unit": "kV"}) == 12.0 * u.units.kV assert u.convert_to_quantity(1.0 * u.units.mV) == 1.0 * u.units.mV def test_set_service_attribute_value_by_path(caplog: LogCaptureFixture) -> None: class ServiceClass(DataService): voltage = 1.0 * u.units.V _current: u.Quantity = 1.0 * u.units.mA @property def current(self) -> u.Quantity: return self._current @current.setter def current(self, value: Any) -> None: self._current = value service_instance = ServiceClass() state_manager = StateManager(service_instance) DataServiceObserver(state_manager) state_manager.set_service_attribute_value_by_path( path="voltage", serialized_value=dump(1.0 * u.units.mV) ) assert "'voltage' changed to '1.0 mV'" in caplog.text caplog.clear() def test_autoconvert_offset_to_baseunit() -> None: import pint assert u.units.autoconvert_offset_to_baseunit is True try: quantity = 10 * u.units.degC except pint.errors.OffsetUnitCalculusError as exc: assert False, f"Offset unit raises exception {exc}" def test_loading_from_json(caplog: LogCaptureFixture) -> None: """This function tests if the quantity read from the json description is actually passed as a quantity to the property setter.""" import json import tempfile serialization_dict = { "some_unit": { "type": "Quantity", "value": {"magnitude": 10.0, "unit": "A"}, "readonly": False, "doc": None, } } class ServiceClass(DataService): def __init__(self) -> None: super().__init__() self._unit: u.Quantity = 1 * u.units.A @property def some_unit(self) -> u.Quantity: return self._unit @some_unit.setter @load_state def some_unit(self, value: u.Quantity) -> None: assert isinstance(value, u.Quantity) self._unit = value service_instance = ServiceClass() fp = tempfile.NamedTemporaryFile("w+") json.dump(serialization_dict, fp) fp.seek(0) pydase.Server(service_instance, filename=fp.name) assert "'some_unit' changed to '10.0 A'" in caplog.text