mirror of
https://github.com/tiqi-group/pydase.git
synced 2025-04-20 00:10:03 +02:00
adds observer_pattern tests
This commit is contained in:
parent
f97cd7eb4e
commit
329e0acd81
159
tests/observer_pattern/observable/test_observable.py
Normal file
159
tests/observer_pattern/observable/test_observable.py
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
import logging
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from pydase.observer_pattern.observable import Observable
|
||||||
|
from pydase.observer_pattern.observer import Observer
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class MyObserver(Observer):
|
||||||
|
def on_change(self, full_access_path: str, value: Any) -> None:
|
||||||
|
logger.info("'%s' changed to '%s'", full_access_path, value)
|
||||||
|
|
||||||
|
|
||||||
|
def test_simple_class_attribute(caplog: pytest.LogCaptureFixture) -> None:
|
||||||
|
class MyObservable(Observable):
|
||||||
|
int_attribute = 10
|
||||||
|
|
||||||
|
instance = MyObservable()
|
||||||
|
observer = MyObserver(instance)
|
||||||
|
instance.int_attribute = 12
|
||||||
|
|
||||||
|
assert "'int_attribute' changed to '12'" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
def test_simple_instance_attribute(caplog: pytest.LogCaptureFixture) -> None:
|
||||||
|
class MyObservable(Observable):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.int_attribute = 10
|
||||||
|
|
||||||
|
instance = MyObservable()
|
||||||
|
observer = MyObserver(instance)
|
||||||
|
instance.int_attribute = 12
|
||||||
|
|
||||||
|
assert "'int_attribute' changed to '12'" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
def test_nested_class_attribute(caplog: pytest.LogCaptureFixture) -> None:
|
||||||
|
class MySubclass(Observable):
|
||||||
|
name = "My Subclass"
|
||||||
|
|
||||||
|
class MyObservable(Observable):
|
||||||
|
subclass = MySubclass()
|
||||||
|
|
||||||
|
instance = MyObservable()
|
||||||
|
observer = MyObserver(instance)
|
||||||
|
instance.subclass.name = "Other name"
|
||||||
|
|
||||||
|
assert "'subclass.name' changed to 'Other name'" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
def test_nested_instance_attribute(caplog: pytest.LogCaptureFixture) -> None:
|
||||||
|
class MySubclass(Observable):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.name = "Subclass name"
|
||||||
|
|
||||||
|
class MyObservable(Observable):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.subclass = MySubclass()
|
||||||
|
|
||||||
|
instance = MyObservable()
|
||||||
|
observer = MyObserver(instance)
|
||||||
|
instance.subclass.name = "Other name"
|
||||||
|
|
||||||
|
assert "'subclass.name' changed to 'Other name'" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
def test_removed_observer_on_class_attr(caplog: pytest.LogCaptureFixture) -> None:
|
||||||
|
class NestedObservable(Observable):
|
||||||
|
name = "Hello"
|
||||||
|
|
||||||
|
nested_instance = NestedObservable()
|
||||||
|
|
||||||
|
class MyObservable(Observable):
|
||||||
|
nested_attr = nested_instance
|
||||||
|
changed_attr = nested_instance
|
||||||
|
|
||||||
|
instance = MyObservable()
|
||||||
|
observer = MyObserver(instance)
|
||||||
|
instance.changed_attr = "Ciao"
|
||||||
|
|
||||||
|
assert "'changed_attr' changed to 'Ciao'" in caplog.text
|
||||||
|
caplog.clear()
|
||||||
|
|
||||||
|
instance.nested_attr.name = "Hi"
|
||||||
|
|
||||||
|
assert "'nested_attr.name' changed to 'Hi'" in caplog.text
|
||||||
|
assert "'changed_attr.name' changed to 'Hi'" not in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
def test_removed_observer_on_instance_attr(caplog: pytest.LogCaptureFixture) -> None:
|
||||||
|
class NestedObservable(Observable):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.name = "Hello"
|
||||||
|
|
||||||
|
nested_instance = NestedObservable()
|
||||||
|
|
||||||
|
class MyObservable(Observable):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.nested_attr = nested_instance
|
||||||
|
self.changed_attr = nested_instance
|
||||||
|
|
||||||
|
instance = MyObservable()
|
||||||
|
observer = MyObserver(instance)
|
||||||
|
instance.changed_attr = "Ciao"
|
||||||
|
|
||||||
|
assert "'changed_attr' changed to 'Ciao'" in caplog.text
|
||||||
|
caplog.clear()
|
||||||
|
|
||||||
|
instance.nested_attr.name = "Hi"
|
||||||
|
|
||||||
|
assert "'nested_attr.name' changed to 'Hi'" in caplog.text
|
||||||
|
assert "'changed_attr.name' changed to 'Hi'" not in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
def test_property_getter(caplog: pytest.LogCaptureFixture) -> None:
|
||||||
|
class MyObservable(Observable):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self._name = "Hello"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self) -> str:
|
||||||
|
"""The name property."""
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
instance = MyObservable()
|
||||||
|
observer = MyObserver(instance)
|
||||||
|
_ = instance.name
|
||||||
|
|
||||||
|
assert "'name' changed to 'Hello'" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
def test_property_setter(caplog: pytest.LogCaptureFixture) -> None:
|
||||||
|
class MyObservable(Observable):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self._name = "Hello"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self) -> str:
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
@name.setter
|
||||||
|
def name(self, value: str) -> None:
|
||||||
|
self._name = value
|
||||||
|
|
||||||
|
instance = MyObservable()
|
||||||
|
observer = MyObserver(instance)
|
||||||
|
instance.name = "Ciao"
|
||||||
|
|
||||||
|
assert "'name' changed to 'Hello'" not in caplog.text
|
||||||
|
assert "'name' changed to 'Ciao'" in caplog.text
|
282
tests/observer_pattern/observable/test_observable_object.py
Normal file
282
tests/observer_pattern/observable/test_observable_object.py
Normal file
@ -0,0 +1,282 @@
|
|||||||
|
import logging
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from pydase.observer_pattern.observable import Observable
|
||||||
|
from pydase.observer_pattern.observer import Observer
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class MyObserver(Observer):
|
||||||
|
def on_change(self, full_access_path: str, value: Any) -> None:
|
||||||
|
logger.info("'%s' changed to '%s'", full_access_path, value)
|
||||||
|
|
||||||
|
|
||||||
|
def test_simple_instance_list_attribute(caplog: pytest.LogCaptureFixture) -> None:
|
||||||
|
class MyObservable(Observable):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.list_attr = [1, 2]
|
||||||
|
|
||||||
|
instance = MyObservable()
|
||||||
|
observer = MyObserver(instance)
|
||||||
|
instance.list_attr[0] = 12
|
||||||
|
|
||||||
|
assert "'list_attr[0]' changed to '12'" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
def test_instance_object_list_attribute(caplog: pytest.LogCaptureFixture) -> None:
|
||||||
|
class NestedObservable(Observable):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.name = "Hello"
|
||||||
|
|
||||||
|
class MyObservable(Observable):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.list_attr = [NestedObservable()]
|
||||||
|
|
||||||
|
instance = MyObservable()
|
||||||
|
observer = MyObserver(instance)
|
||||||
|
instance.list_attr[0].name = "Ciao"
|
||||||
|
|
||||||
|
assert "'list_attr[0].name' changed to 'Ciao'" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
def test_simple_class_list_attribute(caplog: pytest.LogCaptureFixture) -> None:
|
||||||
|
class MyObservable(Observable):
|
||||||
|
list_attr = [1, 2]
|
||||||
|
|
||||||
|
instance = MyObservable()
|
||||||
|
observer = MyObserver(instance)
|
||||||
|
instance.list_attr[0] = 12
|
||||||
|
|
||||||
|
assert "'list_attr[0]' changed to '12'" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
def test_class_object_list_attribute(caplog: pytest.LogCaptureFixture) -> None:
|
||||||
|
class NestedObservable(Observable):
|
||||||
|
name = "Hello"
|
||||||
|
|
||||||
|
class MyObservable(Observable):
|
||||||
|
list_attr = [NestedObservable()]
|
||||||
|
|
||||||
|
instance = MyObservable()
|
||||||
|
observer = MyObserver(instance)
|
||||||
|
instance.list_attr[0].name = "Ciao"
|
||||||
|
|
||||||
|
assert "'list_attr[0].name' changed to 'Ciao'" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
def test_simple_instance_dict_attribute(caplog: pytest.LogCaptureFixture) -> None:
|
||||||
|
class MyObservable(Observable):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.dict_attr = {"first": "Hello"}
|
||||||
|
|
||||||
|
instance = MyObservable()
|
||||||
|
observer = MyObserver(instance)
|
||||||
|
instance.dict_attr["first"] = "Ciao"
|
||||||
|
instance.dict_attr["second"] = "World"
|
||||||
|
|
||||||
|
assert "'dict_attr['first']' changed to 'Ciao'" in caplog.text
|
||||||
|
assert "'dict_attr['second']' changed to 'World'" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
def test_simple_class_dict_attribute(caplog: pytest.LogCaptureFixture) -> None:
|
||||||
|
class MyObservable(Observable):
|
||||||
|
dict_attr = {"first": "Hello"}
|
||||||
|
|
||||||
|
instance = MyObservable()
|
||||||
|
observer = MyObserver(instance)
|
||||||
|
instance.dict_attr["first"] = "Ciao"
|
||||||
|
instance.dict_attr["second"] = "World"
|
||||||
|
|
||||||
|
assert "'dict_attr['first']' changed to 'Ciao'" in caplog.text
|
||||||
|
assert "'dict_attr['second']' changed to 'World'" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
def test_instance_dict_attribute(caplog: pytest.LogCaptureFixture) -> None:
|
||||||
|
class NestedObservable(Observable):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.name = "Hello"
|
||||||
|
|
||||||
|
class MyObservable(Observable):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.dict_attr = {"first": NestedObservable()}
|
||||||
|
|
||||||
|
instance = MyObservable()
|
||||||
|
observer = MyObserver(instance)
|
||||||
|
instance.dict_attr["first"].name = "Ciao"
|
||||||
|
|
||||||
|
assert "'dict_attr['first'].name' changed to 'Ciao'" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
def test_class_dict_attribute(caplog: pytest.LogCaptureFixture) -> None:
|
||||||
|
class NestedObservable(Observable):
|
||||||
|
name = "Hello"
|
||||||
|
|
||||||
|
class MyObservable(Observable):
|
||||||
|
dict_attr = {"first": NestedObservable()}
|
||||||
|
|
||||||
|
instance = MyObservable()
|
||||||
|
observer = MyObserver(instance)
|
||||||
|
instance.dict_attr["first"].name = "Ciao"
|
||||||
|
|
||||||
|
assert "'dict_attr['first'].name' changed to 'Ciao'" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
def test_removed_observer_on_class_list_attr(caplog: pytest.LogCaptureFixture) -> None:
|
||||||
|
class NestedObservable(Observable):
|
||||||
|
name = "Hello"
|
||||||
|
|
||||||
|
nested_instance = NestedObservable()
|
||||||
|
|
||||||
|
class MyObservable(Observable):
|
||||||
|
nested_attr = nested_instance
|
||||||
|
changed_list_attr = [nested_instance]
|
||||||
|
|
||||||
|
instance = MyObservable()
|
||||||
|
observer = MyObserver(instance)
|
||||||
|
instance.changed_list_attr[0] = "Ciao"
|
||||||
|
|
||||||
|
assert "'changed_list_attr[0]' changed to 'Ciao'" in caplog.text
|
||||||
|
caplog.clear()
|
||||||
|
|
||||||
|
instance.nested_attr.name = "Hi"
|
||||||
|
|
||||||
|
assert "'nested_attr.name' changed to 'Hi'" in caplog.text
|
||||||
|
assert "'changed_list_attr[0].name' changed to 'Hi'" not in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
def test_removed_observer_on_instance_dict_attr(
|
||||||
|
caplog: pytest.LogCaptureFixture,
|
||||||
|
) -> None:
|
||||||
|
class NestedObservable(Observable):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.name = "Hello"
|
||||||
|
|
||||||
|
nested_instance = NestedObservable()
|
||||||
|
|
||||||
|
class MyObservable(Observable):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.nested_attr = nested_instance
|
||||||
|
self.changed_dict_attr = {"nested": nested_instance}
|
||||||
|
|
||||||
|
instance = MyObservable()
|
||||||
|
observer = MyObserver(instance)
|
||||||
|
instance.changed_dict_attr["nested"] = "Ciao"
|
||||||
|
|
||||||
|
assert "'changed_dict_attr['nested']' changed to 'Ciao'" in caplog.text
|
||||||
|
caplog.clear()
|
||||||
|
|
||||||
|
instance.nested_attr.name = "Hi"
|
||||||
|
|
||||||
|
assert "'nested_attr.name' changed to 'Hi'" in caplog.text
|
||||||
|
assert "'changed_dict_attr['nested'].name' changed to 'Hi'" not in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
def test_removed_observer_on_instance_list_attr(
|
||||||
|
caplog: pytest.LogCaptureFixture,
|
||||||
|
) -> None:
|
||||||
|
class NestedObservable(Observable):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.name = "Hello"
|
||||||
|
|
||||||
|
nested_instance = NestedObservable()
|
||||||
|
|
||||||
|
class MyObservable(Observable):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.nested_attr = nested_instance
|
||||||
|
self.changed_list_attr = [nested_instance]
|
||||||
|
|
||||||
|
instance = MyObservable()
|
||||||
|
observer = MyObserver(instance)
|
||||||
|
instance.changed_list_attr[0] = "Ciao"
|
||||||
|
|
||||||
|
assert "'changed_list_attr[0]' changed to 'Ciao'" in caplog.text
|
||||||
|
caplog.clear()
|
||||||
|
|
||||||
|
instance.nested_attr.name = "Hi"
|
||||||
|
|
||||||
|
assert "'nested_attr.name' changed to 'Hi'" in caplog.text
|
||||||
|
assert "'changed_list_attr[0].name' changed to 'Hi'" not in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
def test_removed_observer_on_class_dict_attr(caplog: pytest.LogCaptureFixture) -> None:
|
||||||
|
class NestedObservable(Observable):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.name = "Hello"
|
||||||
|
|
||||||
|
nested_instance = NestedObservable()
|
||||||
|
|
||||||
|
class MyObservable(Observable):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.nested_attr = nested_instance
|
||||||
|
self.changed_dict_attr = {"nested": nested_instance}
|
||||||
|
|
||||||
|
instance = MyObservable()
|
||||||
|
observer = MyObserver(instance)
|
||||||
|
instance.changed_dict_attr["nested"] = "Ciao"
|
||||||
|
|
||||||
|
assert "'changed_dict_attr['nested']' changed to 'Ciao'" in caplog.text
|
||||||
|
caplog.clear()
|
||||||
|
|
||||||
|
instance.nested_attr.name = "Hi"
|
||||||
|
|
||||||
|
assert "'nested_attr.name' changed to 'Hi'" in caplog.text
|
||||||
|
assert "'changed_dict_attr['nested'].name' changed to 'Hi'" not in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
def test_nested_dict_instances(caplog: pytest.LogCaptureFixture) -> None:
|
||||||
|
dict_instance = {"first": "Hello", "second": "World"}
|
||||||
|
|
||||||
|
class MyObservable(Observable):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.nested_dict_attr = {"nested": dict_instance}
|
||||||
|
|
||||||
|
instance = MyObservable()
|
||||||
|
observer = MyObserver(instance)
|
||||||
|
instance.nested_dict_attr["nested"]["first"] = "Ciao"
|
||||||
|
|
||||||
|
assert "'nested_dict_attr['nested']['first']' changed to 'Ciao'" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
def test_dict_in_list_instance(caplog: pytest.LogCaptureFixture) -> None:
|
||||||
|
dict_instance = {"first": "Hello", "second": "World"}
|
||||||
|
|
||||||
|
class MyObservable(Observable):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.dict_in_list = [dict_instance]
|
||||||
|
|
||||||
|
instance = MyObservable()
|
||||||
|
observer = MyObserver(instance)
|
||||||
|
instance.dict_in_list[0]["first"] = "Ciao"
|
||||||
|
|
||||||
|
assert "'dict_in_list[0]['first']' changed to 'Ciao'" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
def test_list_in_dict_instance(caplog: pytest.LogCaptureFixture) -> None:
|
||||||
|
list_instance = [1, 2, 3]
|
||||||
|
|
||||||
|
class MyObservable(Observable):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.list_in_dict = {"some_list": list_instance}
|
||||||
|
|
||||||
|
instance = MyObservable()
|
||||||
|
observer = MyObserver(instance)
|
||||||
|
instance.list_in_dict["some_list"][0] = "Ciao"
|
||||||
|
|
||||||
|
assert "'list_in_dict['some_list'][0]' changed to 'Ciao'" in caplog.text
|
25
tests/observer_pattern/observer/test_observer.py
Normal file
25
tests/observer_pattern/observer/test_observer.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from pydase.observer_pattern.observable import Observable
|
||||||
|
from pydase.observer_pattern.observer import Observer
|
||||||
|
|
||||||
|
|
||||||
|
def test_abstract_method_error() -> None:
|
||||||
|
class MyObserver(Observer):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class MyObservable(Observable):
|
||||||
|
pass
|
||||||
|
|
||||||
|
with pytest.raises(TypeError):
|
||||||
|
MyObserver(MyObservable())
|
||||||
|
|
||||||
|
|
||||||
|
def test_constructor_error() -> None:
|
||||||
|
class MyObserver(Observer):
|
||||||
|
def on_change(self, full_access_path: str, value: Any) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
with pytest.raises(TypeError):
|
||||||
|
MyObserver()
|
Loading…
x
Reference in New Issue
Block a user