Initial commit

This commit is contained in:
Mose Müller
2023-08-02 12:06:19 +02:00
parent cda7955934
commit b67c0f9da3
19 changed files with 1868 additions and 0 deletions

0
tests/__init__.py Normal file
View File

View File

View File

@ -0,0 +1,138 @@
from typing import Any
from pytest import CaptureFixture
from pyDataInterface import DataService
def emit(self: Any, access_path: set[str], name: str, value: Any) -> None:
if isinstance(value, DataService):
value = value.serialize()
for path in access_path:
print(f"{path}.{name} = {value}")
DataService._emit = emit # type: ignore
def test_class_attribute(capsys: CaptureFixture) -> None:
class ServiceClass(DataService):
attr = 0
service_instance = ServiceClass()
service_instance.attr = 1
captured = capsys.readouterr()
assert captured.out == "ServiceClass.attr = 1\n"
def test_instance_attribute(capsys: CaptureFixture) -> None:
class ServiceClass(DataService):
def __init__(self) -> None:
self.attr = "Hello World"
super().__init__()
service_instance = ServiceClass()
service_instance.attr = "Hello"
captured = capsys.readouterr()
assert captured.out == "ServiceClass.attr = Hello\n"
def test_class_list_attribute(capsys: CaptureFixture) -> None:
class ServiceClass(DataService):
attr = [0, 1]
service_instance = ServiceClass()
service_instance.attr[0] = 1337
captured = capsys.readouterr()
assert captured.out == "ServiceClass.attr[0] = 1337\n"
def test_instance_list_attribute(capsys: CaptureFixture) -> None:
class SubClass(DataService):
name = "SubClass"
class ServiceClass(DataService):
def __init__(self) -> None:
self.attr = [0, SubClass()]
super().__init__()
service_instance = ServiceClass()
_ = capsys.readouterr()
service_instance.attr[0] = "Hello"
captured = capsys.readouterr()
assert captured.out == "ServiceClass.attr[0] = Hello\n"
service_instance.attr[1] = SubClass()
captured = capsys.readouterr()
assert (
captured.out.strip()
== "ServiceClass.attr[1] = {'name': {'type': 'str', 'value': 'SubClass',"
" 'readonly': False}}"
)
def test_reused_instance_list_attribute(capsys: CaptureFixture) -> None:
some_list = [0, 1, 2]
class ServiceClass(DataService):
def __init__(self) -> None:
self.attr = some_list
self.attr_2 = some_list
self.attr_3 = [0, 1, 2]
super().__init__()
service_instance = ServiceClass()
service_instance.attr[0] = "Hello"
captured = capsys.readouterr()
assert service_instance.attr == service_instance.attr_2
assert service_instance.attr != service_instance.attr_3
expected_output = sorted(
[
"ServiceClass.attr[0] = Hello",
"ServiceClass.attr_2[0] = Hello",
]
)
actual_output = sorted(captured.out.strip().split("\n"))
assert actual_output == expected_output
def test_nested_reused_instance_list_attribute(capsys: CaptureFixture) -> None:
some_list = [0, 1, 2]
class SubClass(DataService):
attr_list = some_list
def __init__(self) -> None:
self.attr_list_2 = some_list
super().__init__()
class ServiceClass(DataService):
def __init__(self) -> None:
self.attr = some_list
self.subclass = SubClass()
super().__init__()
service_instance = ServiceClass()
_ = capsys.readouterr()
service_instance.attr[0] = "Hello"
captured = capsys.readouterr()
assert service_instance.attr == service_instance.subclass.attr_list
expected_output = sorted(
[
"ServiceClass.subclass.attr_list_2[0] = Hello",
"ServiceClass.subclass.attr_list[0] = Hello",
"ServiceClass.attr[0] = Hello",
]
)
actual_output = sorted(captured.out.strip().split("\n"))
assert actual_output == expected_output

View File

@ -0,0 +1,364 @@
from pyDataInterface import DataService
def test_class_attributes() -> None:
class SubClass(DataService):
pass
class ServiceClass(DataService):
attr_1 = SubClass()
test_service = ServiceClass()
assert test_service.attr_1._full_access_path == {"ServiceClass.attr_1"}
def test_instance_attributes() -> None:
class SubClass(DataService):
pass
class ServiceClass(DataService):
def __init__(self):
self.attr_1 = SubClass()
super().__init__()
test_service = ServiceClass()
assert test_service.attr_1._full_access_path == {"ServiceClass.attr_1"}
def test_reused_instance_attributes() -> None:
class SubClass(DataService):
pass
subclass_instance = SubClass()
class ServiceClass(DataService):
def __init__(self):
self.attr_1 = subclass_instance
self.attr_2 = subclass_instance
super().__init__()
test_service = ServiceClass()
assert test_service.attr_1._full_access_path == {
"ServiceClass.attr_1",
"ServiceClass.attr_2",
}
assert test_service.attr_2._full_access_path == {
"ServiceClass.attr_1",
"ServiceClass.attr_2",
}
assert test_service.attr_1._full_access_path == {
"ServiceClass.attr_1",
"ServiceClass.attr_2",
}
def test_reused_attributes_mixed() -> None:
class SubClass(DataService):
pass
subclass_instance = SubClass()
class ServiceClass(DataService):
attr_1 = subclass_instance
def __init__(self):
self.attr_2 = subclass_instance
super().__init__()
test_service = ServiceClass()
assert test_service.attr_1._full_access_path == {
"ServiceClass.attr_1",
"ServiceClass.attr_2",
}
assert test_service.attr_2._full_access_path == {
"ServiceClass.attr_1",
"ServiceClass.attr_2",
}
def test_nested_class_attributes() -> None:
class SubSubSubClass(DataService):
pass
class SubSubClass(DataService):
attr = SubSubSubClass()
class SubClass(DataService):
attr = SubSubClass()
class ServiceClass(DataService):
attr = SubClass()
test_service = ServiceClass()
assert test_service.attr._full_access_path == {
"ServiceClass.attr",
}
assert test_service.attr.attr._full_access_path == {
"ServiceClass.attr.attr",
}
assert test_service.attr.attr.attr._full_access_path == {
"ServiceClass.attr.attr.attr",
}
def test_nested_instance_attributes() -> None:
class SubSubSubClass(DataService):
pass
class SubSubClass(DataService):
def __init__(self):
self.attr = SubSubSubClass()
super().__init__()
class SubClass(DataService):
def __init__(self):
self.attr = SubSubClass()
super().__init__()
class ServiceClass(DataService):
def __init__(self):
self.attr = SubClass()
super().__init__()
test_service = ServiceClass()
assert test_service.attr._full_access_path == {
"ServiceClass.attr",
}
assert test_service.attr.attr._full_access_path == {
"ServiceClass.attr.attr",
}
assert test_service.attr.attr.attr._full_access_path == {
"ServiceClass.attr.attr.attr",
}
def test_advanced_nested_instance_attributes() -> None:
class SubSubSubClass(DataService):
pass
class SubSubClass(DataService):
def __init__(self):
self.attr = SubSubSubClass()
super().__init__()
subsubclass_instance = SubSubClass()
class SubClass(DataService):
def __init__(self):
self.attr = subsubclass_instance
super().__init__()
class ServiceClass(DataService):
def __init__(self):
self.attr = SubClass()
self.subattr = subsubclass_instance
super().__init__()
test_service = ServiceClass()
assert test_service.attr._full_access_path == {
"ServiceClass.attr",
}
assert test_service.attr.attr._full_access_path == {
"ServiceClass.attr.attr",
"ServiceClass.subattr",
}
assert test_service.attr.attr.attr._full_access_path == {
"ServiceClass.attr.attr.attr",
"ServiceClass.subattr.attr", # as the SubSubSubClass does not implement anything, both subattr.attr and attr.attr.attr refer to the same instance
}
def test_advanced_nested_class_attributes() -> None:
class SubSubSubClass(DataService):
pass
class SubSubClass(DataService):
attr = SubSubSubClass()
class SubClass(DataService):
attr = SubSubClass()
class ServiceClass(DataService):
attr = SubClass()
subattr = SubSubClass()
test_service = ServiceClass()
assert test_service.attr._full_access_path == {
"ServiceClass.attr",
}
assert test_service.subattr._full_access_path == {
"ServiceClass.subattr",
}
assert test_service.attr.attr._full_access_path == {
"ServiceClass.attr.attr",
}
assert test_service.attr.attr.attr._full_access_path == {
"ServiceClass.attr.attr.attr",
"ServiceClass.subattr.attr", # as the SubSubSubClass does not implement anything, both subattr.attr and attr.attr.attr refer to the same instance
}
def test_advanced_nested_attributes_mixed() -> None:
class SubSubClass(DataService):
pass
class SubClass(DataService):
attr = SubSubClass()
def __init__(self):
self.attr_1 = SubSubClass()
super().__init__()
class ServiceClass(DataService):
subattr = SubClass()
def __init__(self):
self.attr = SubClass()
super().__init__()
test_service = ServiceClass()
assert test_service.attr._full_access_path == {
"ServiceClass.attr",
}
assert test_service.subattr._full_access_path == {
"ServiceClass.subattr",
}
# Subclass.attr is the same for all instances
assert test_service.attr.attr == test_service.subattr.attr
assert test_service.attr.attr._full_access_path == {
"ServiceClass.attr.attr",
"ServiceClass.subattr.attr",
}
assert test_service.subattr.attr._full_access_path == {
"ServiceClass.subattr.attr",
"ServiceClass.attr.attr",
}
# attr_1 is different for all instances of SubClass
assert test_service.attr.attr_1 != test_service.subattr.attr
assert test_service.attr.attr_1 != test_service.subattr.attr_1
assert test_service.subattr.attr_1._full_access_path == {
"ServiceClass.subattr.attr_1",
}
assert test_service.attr.attr_1._full_access_path == {
"ServiceClass.attr.attr_1",
}
def test_class_list_attributes() -> None:
class SubClass(DataService):
pass
subclass_instance = SubClass()
class ServiceClass(DataService):
attr_list = [SubClass() for _ in range(2)]
attr_list_2 = [subclass_instance, subclass_instance]
attr = subclass_instance
test_service = ServiceClass()
assert test_service.attr_list[0] != test_service.attr_list[1]
assert test_service.attr_list[0]._full_access_path == {
"ServiceClass.attr_list[0]",
}
assert test_service.attr_list[1]._full_access_path == {
"ServiceClass.attr_list[1]",
}
assert test_service.attr_list_2[0] == test_service.attr
assert test_service.attr_list_2[0] == test_service.attr_list_2[1]
assert test_service.attr_list_2[0]._full_access_path == {
"ServiceClass.attr",
"ServiceClass.attr_list_2[0]",
"ServiceClass.attr_list_2[1]",
}
assert test_service.attr_list_2[1]._full_access_path == {
"ServiceClass.attr",
"ServiceClass.attr_list_2[0]",
"ServiceClass.attr_list_2[1]",
}
def test_nested_class_list_attributes() -> None:
class SubSubClass(DataService):
pass
subsubclass_instance = SubSubClass()
class SubClass(DataService):
attr_list = [subsubclass_instance]
class ServiceClass(DataService):
attr = [SubClass()]
subattr = subsubclass_instance
test_service = ServiceClass()
assert test_service.attr[0].attr_list[0] == test_service.subattr
assert test_service.attr[0].attr_list[0]._full_access_path == {
"ServiceClass.attr[0].attr_list[0]",
"ServiceClass.subattr",
}
def test_instance_list_attributes() -> None:
class SubClass(DataService):
pass
subclass_instance = SubClass()
class ServiceClass(DataService):
def __init__(self):
self.attr_list = [SubClass() for _ in range(2)]
self.attr_list_2 = [subclass_instance, subclass_instance]
self.attr = subclass_instance
super().__init__()
test_service = ServiceClass()
assert test_service.attr_list[0] != test_service.attr_list[1]
assert test_service.attr_list[0]._full_access_path == {
"ServiceClass.attr_list[0]",
}
assert test_service.attr_list[1]._full_access_path == {
"ServiceClass.attr_list[1]",
}
assert test_service.attr_list_2[0] == test_service.attr
assert test_service.attr_list_2[0] == test_service.attr_list_2[1]
assert test_service.attr_list_2[0]._full_access_path == {
"ServiceClass.attr",
"ServiceClass.attr_list_2[0]",
"ServiceClass.attr_list_2[1]",
}
assert test_service.attr_list_2[1]._full_access_path == {
"ServiceClass.attr",
"ServiceClass.attr_list_2[0]",
"ServiceClass.attr_list_2[1]",
}
def test_nested_instance_list_attributes() -> None:
class SubSubClass(DataService):
pass
subsubclass_instance = SubSubClass()
class SubClass(DataService):
def __init__(self):
self.attr_list = [subsubclass_instance]
super().__init__()
class ServiceClass(DataService):
subattr = subsubclass_instance
def __init__(self):
self.attr = [SubClass()]
super().__init__()
test_service = ServiceClass()
assert test_service.attr[0].attr_list[0] == test_service.subattr
assert test_service.attr[0].attr_list[0]._full_access_path == {
"ServiceClass.attr[0].attr_list[0]",
"ServiceClass.subattr",
}

34
tests/test_properties.py Normal file
View File

@ -0,0 +1,34 @@
from pytest import CaptureFixture
from pyDataInterface import DataService
def test_properties(capsys: CaptureFixture) -> None:
class ServiceClass(DataService):
_power = True
@property
def power(self) -> bool:
return self._power
@power.setter
def power(self, value: bool) -> None:
self._power = value
@property
def power_two(self) -> bool:
return self._power
test_service = ServiceClass()
test_service.power = False
captured = capsys.readouterr()
expected_output = sorted(
[
"ServiceClass.power = False",
"ServiceClass.power_two = False",
"ServiceClass._power = False",
]
)
actual_output = sorted(captured.out.strip().split("\n"))
assert actual_output == expected_output