diff --git a/ppa/in_memory.py b/ppa/in_memory.py index 540c373..8ea1ff1 100644 --- a/ppa/in_memory.py +++ b/ppa/in_memory.py @@ -1,43 +1,40 @@ +from collections.abc import Iterable from typing import Any, Type def in_memory_repository( + find_by_fields: Iterable[str] | None = None, entity_already_exists_exception: Type[Exception] = ValueError, entity_not_found_exception: Type[Exception] = ValueError, ): + if find_by_fields is None: + find_by_fields = [] def decorator(cls) -> Type: - e_already_exists = entity_already_exists_exception - e_not_found = entity_not_found_exception - class InMemoryRepository(cls): - find_by_fields: list[str] = ["id"] - entity_already_exists_exception: Type[Exception] = e_already_exists - entity_not_found_exception: Type[Exception] = e_not_found - def __init__(self) -> None: self._store: dict[str, Any] = {} - for key in self.find_by_fields: + for key in find_by_fields: setattr(self, f"find_by_{key}", self._make_find_by_method(key)) def add(self, entity: Any) -> Any: if entity.id in self._store: - raise self.entity_already_exists_exception() + raise entity_already_exists_exception() self._store[entity.id] = entity def retrieve(self, id_: Any) -> Any: try: return self._store[id_] except KeyError as err: - raise self.entity_not_found_exception() from err + raise entity_not_found_exception() from err def update(self, entity: Any) -> None: if entity.id not in self._store: - raise self.entity_not_found_exception() + raise entity_not_found_exception() self._store[entity.id] = entity def delete(self, id_: Any) -> None: if id_ not in self._store: - raise self.entity_not_found_exception(id_) + raise entity_not_found_exception() del self._store[id_] def _make_find_by_method(self, field_name: str) -> Any: diff --git a/ppa/test/test_in_memory.py b/ppa/test/test_in_memory.py index 0cd4fce..d735cd5 100644 --- a/ppa/test/test_in_memory.py +++ b/ppa/test/test_in_memory.py @@ -3,36 +3,83 @@ from ppa.in_memory import in_memory_repository +class User: + def __init__(self, id_: int, name: str): + self.id = id_ + self.name = name @pytest.fixture -def User(): - class User: - def __init__(self, id_: int, name: str): - self.id = id_ - self.name = name - - return User +def user(): + return User(1, 'john') +@in_memory_repository(find_by_fields=[]) +class UserRepository: + pass @pytest.fixture def user_repository(): - @in_memory_repository() - class UserRepository: + return UserRepository() + + +def test_in_memory_repository_find_by_fields(user: User): + @in_memory_repository(find_by_fields=("id", "name")) + class FieldsRepository: pass - return UserRepository() + rep = FieldsRepository() + rep.add(user) -def test_in_memory_repository(user_repository, User): - user = User(id_=1, name="John") + assert rep.find_by_id(user.id) == [user] + assert rep.find_by_name(user.name) == [user] - user_repository.add(user) - retrieved_user = user_repository.retrieve(1) - assert retrieved_user == user +def test_in_memory_repository_exceptions(user: User): + class CustomException1(Exception): + pass + + class CustomException2(Exception): + pass + + @in_memory_repository( + entity_already_exists_exception=CustomException1, + entity_not_found_exception=CustomException2, + ) + class ExceptionsRepository: + pass + + + rep = ExceptionsRepository() - updated_user = User(id_=1, name="Johny") + with pytest.raises(CustomException2): + rep.delete(user.id) + + rep.add(user) + with pytest.raises(CustomException1): + rep.add(user) + + +def test_in_memory_repository_methods(user_repository: UserRepository, user: User): + user_repository.add(user) + assert user_repository.retrieve(user.id) == user + updated_user = User(id_=user.id, name="john_updated") user_repository.update(updated_user) - assert user_repository.retrieve(1) == updated_user + modified_user = user_repository.retrieve(user.id) + assert modified_user.id == updated_user.id and modified_user.name == updated_user.name + user_repository.delete(user.id) + with pytest.raises(ValueError): + assert user_repository.retrieve(user.id) + - user_repository.delete(1) +def test_in_memory_repository_add_already_exists(user_repository: UserRepository, user: User): + user_repository.add(user) with pytest.raises(ValueError): - user_repository.retrieve(1) + user_repository.add(user) + +def test_in_memory_repository_update_not_found(user_repository: UserRepository, user: User): + with pytest.raises(ValueError): + user_repository.update(user) + + +def test_in_memory_repository_delete_not_found(user_repository: UserRepository, user: User): + with pytest.raises(ValueError): + user_repository.delete(user) +