From d057710b60181ae46fd0a2eaabc0ff6861a23135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mose=20M=C3=BCller?= Date: Mon, 6 Nov 2023 17:22:26 +0100 Subject: [PATCH] adds StateManager tests --- tests/data_service/test_state_manager.py | 142 +++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 tests/data_service/test_state_manager.py diff --git a/tests/data_service/test_state_manager.py b/tests/data_service/test_state_manager.py new file mode 100644 index 0000000..f5674df --- /dev/null +++ b/tests/data_service/test_state_manager.py @@ -0,0 +1,142 @@ +import json +from pathlib import Path +from typing import Any + +from pytest import LogCaptureFixture + +import pydase +import pydase.units as u +from pydase.data_service.state_manager import StateManager + + +class Service(pydase.DataService): + def __init__(self, **kwargs: Any) -> None: + self.some_unit: u.Quantity = 1.2 * u.units.A + self.some_float = 1.0 + self._name = "Service" + super().__init__(**kwargs) + + @property + def name(self) -> str: + return self._name + + +CURRENT_STATE = { + "name": { + "type": "str", + "value": "Service", + "readonly": True, + "doc": None, + }, + "some_float": { + "type": "float", + "value": 1.0, + "readonly": False, + "doc": None, + }, + "some_unit": { + "type": "Quantity", + "value": {"magnitude": 1.2, "unit": "A"}, + "readonly": False, + "doc": None, + }, +} + +LOAD_STATE = { + "name": { + "type": "str", + "value": "Service", + "readonly": True, + "doc": None, + }, + "some_float": { + "type": "int", + "value": 1, + "readonly": False, + "doc": None, + }, + "some_unit": { + "type": "Quantity", + "value": {"magnitude": 12.0, "unit": "A"}, + "readonly": False, + "doc": None, + }, +} + + +def test_save_state(tmp_path: Path): + # Create a StateManager instance with a temporary file + file = tmp_path / "test_state.json" + manager = StateManager(service=Service(), filename=str(file)) + + # Trigger the saving action + manager.save_state() + + # Now check that the file was written correctly + assert file.read_text() == json.dumps(CURRENT_STATE, indent=4) + + +def test_load_state(tmp_path: Path): + # Create a StateManager instance with a temporary file + file = tmp_path / "test_state.json" + + # Write a temporary JSON file to read back + with open(file, "w") as f: + json.dump(LOAD_STATE, f, indent=4) + + service = Service() + manager = StateManager(service=service, filename=str(file)) + manager.load_state() + assert service.some_unit == u.Quantity(12, "A") + + +def test_filename_warning(tmp_path: Path, caplog: LogCaptureFixture): + file = tmp_path / "test_state.json" + + service = Service(filename=str(file)) + StateManager(service=service, filename=str(file)) + assert f"Overwriting filename {str(file)!r} with {str(file)!r}." in caplog.text + + +def test_filename_error(caplog: LogCaptureFixture): + service = Service() + manager = StateManager(service=service) + + manager.save_state() + assert ( + "State manager was not initialised with a filename. Skipping 'save_state'..." + in caplog.text + ) + + +def test_readonly_attribute(tmp_path: Path, caplog: LogCaptureFixture): + # Create a StateManager instance with a temporary file + file = tmp_path / "test_state.json" + + # Write a temporary JSON file to read back + with open(file, "w") as f: + json.dump(LOAD_STATE, f, indent=4) + + service = Service() + manager = StateManager(service=service, filename=str(file)) + manager.load_state() + assert ( + "Attribute 'name' is read-only. Ignoring value from JSON file..." in caplog.text + ) + + +def test_changed_type(tmp_path: Path, caplog: LogCaptureFixture): + # Create a StateManager instance with a temporary file + file = tmp_path / "test_state.json" + + # Write a temporary JSON file to read back + with open(file, "w") as f: + json.dump(LOAD_STATE, f, indent=4) + + service = Service() + manager = StateManager(service=service, filename=str(file)) + manager.load_state() + assert ( + "Attribute type of 'some_float' changed from 'int' to " + "'float'. Ignoring value from JSON file..." + ) in caplog.text