Skip to content

Commit ddc9829

Browse files
committed
test: add more backend testing
1 parent ec6ecbc commit ddc9829

File tree

8 files changed

+128
-46
lines changed

8 files changed

+128
-46
lines changed

src/mastermind/client/languages/localization.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,30 @@
22
from pathlib import Path
33
from typing import Any, Dict
44

5+
from mastermind.libs.logs import ClientLogger
56
from mastermind.libs.utils import CallableDotDict
67

78
JSON = list[Any] | dict[str, Any]
9+
logger = ClientLogger("Localization")
810

911

1012
class Localization:
11-
"""Localization class for printing messages in different languages."""
13+
"""Localization class for printing messages in different languages.
14+
15+
Examples:
16+
>>> localization = Localization(language="en")
17+
>>> localization.language
18+
'en'
19+
>>> localization.menu.main_menu.menu_title
20+
'Main Menu'
21+
>>> localization.language = "zh"
22+
>>> localization.menu.main_menu.menu_title
23+
'主菜单'
24+
>>> localization.language = "unsupported_language"
25+
Traceback (most recent call last):
26+
...
27+
FileNotFoundError: Language pack for 'unsupported_language' not found.
28+
"""
1229

1330
_language_pack: Dict[str, CallableDotDict] = {}
1431

@@ -22,6 +39,7 @@ def language(self) -> str:
2239
@language.setter
2340
def language(self, language: str) -> None:
2441
"""Set and load new language."""
42+
logger.debug(f"Setting language to: {language}")
2543
self.messages: CallableDotDict = self.load_language_pack(language)
2644
self._language: str = language
2745

@@ -32,6 +50,7 @@ def load_language_pack(self, language: str) -> CallableDotDict:
3250

3351
file_path = Path(f"{Path(__file__).parent}/{language}.json")
3452
if not file_path.is_file():
53+
logger.error(f"Language pack for '{language}' not found.")
3554
raise FileNotFoundError(f"Language pack for '{language}' not found.")
3655

3756
with open(file_path, "r", encoding="utf-8") as f:
@@ -41,6 +60,7 @@ def print_message(message: str, **kwargs: Any) -> str:
4160

4261
data: JSON = json.load(f)
4362
self._language_pack[language] = CallableDotDict(data, func=print_message)
63+
logger.info(f"Language pack for '{language}' loaded successfully")
4464
return self._language_pack[language]
4565

4666
def __getattr__(self, item: str) -> CallableDotDict:
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from .app import app
2+
3+
__all__ = ["app"]

src/mastermind/server/database/io/cattrs_multifiles_handler.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,6 @@ def delete(self, key: str) -> None:
142142
try:
143143
os.remove(os.path.join(self.path, f"{key}.json"))
144144

145-
except FileNotFoundError as e:
146-
_log_exception(f"File {key}.json does not exist in {self.path}", e)
147-
148145
except Exception as e:
149146
_log_exception(f"Error deleting {key}.json", e)
150147

src/tests/conftest.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from tempfile import TemporaryDirectory
2+
from typing import Any, Generator
3+
4+
import pytest
5+
6+
from mastermind.server.database.enum import GameMode
7+
from mastermind.server.database.models import Game, GameConfiguration
8+
from mastermind.server.database.repository import GameRepository
9+
from mastermind.server.services import GameboardService, GameService
10+
11+
12+
@pytest.fixture
13+
def game_configuration() -> GameConfiguration:
14+
return GameConfiguration(
15+
NUMBER_OF_COLORS=3,
16+
NUMBER_OF_DOTS=4,
17+
ATTEMPTS_ALLOWED=5,
18+
GAME_MODE=GameMode.PVP,
19+
)
20+
21+
22+
@pytest.fixture
23+
def game(game_configuration: GameConfiguration) -> Game:
24+
return Game(game_configuration=game_configuration)
25+
26+
27+
@pytest.fixture
28+
def gameboard_service(game: Game) -> GameboardService:
29+
return GameboardService(game.game_board)
30+
31+
32+
@pytest.fixture
33+
def game_service(game: Game, gameboard_service: GameboardService) -> GameService:
34+
return GameService(game, gameboard_service)
35+
36+
37+
@pytest.fixture
38+
def game_repository() -> Generator[GameRepository, Any, None]:
39+
with TemporaryDirectory() as temp_dir:
40+
yield GameRepository(temp_dir)

src/tests/libs/__init__.py

Whitespace-only changes.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from dataclasses import dataclass
2+
3+
import pytest
4+
5+
from mastermind.server.database.repository import GameRepository
6+
7+
8+
@pytest.fixture
9+
def unexpected_object() -> object:
10+
class UnexpectedObject:
11+
some_field: str = "Hello, World!"
12+
13+
return UnexpectedObject()
14+
15+
16+
@pytest.fixture
17+
def unexpected_serializable() -> object:
18+
@dataclass
19+
class UnexpectedSerializable:
20+
some_field: str = "Hello, World!"
21+
22+
return UnexpectedSerializable()
23+
24+
25+
def test_delete_nonexistent_file(game_repository: GameRepository) -> None:
26+
with pytest.raises(FileNotFoundError):
27+
game_repository.io_handler.delete("nonexistent_file")
28+
29+
30+
def test_repository_unexpected_object(
31+
game_repository: GameRepository, unexpected_object: object
32+
) -> None:
33+
with pytest.raises(TypeError):
34+
game_repository.add(unexpected_object) # type: ignore
35+
36+
37+
def test_io_handling_unexpected_serializable(
38+
game_repository: GameRepository, unexpected_serializable: object
39+
) -> None:
40+
game_repository.io_handler.add("unexpected_serializable", unexpected_serializable) # type: ignore
41+
42+
with pytest.raises(Exception):
43+
game_repository["unexpected_serializable"] # type: ignore
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,10 @@
1-
from tempfile import TemporaryDirectory
2-
from typing import Any, Generator
3-
41
import pytest
52

63
from mastermind.server.database.enum import GameMode
74
from mastermind.server.database.models import Game, GameConfiguration
85
from mastermind.server.database.repository import GameRepository
96

107

11-
@pytest.fixture
12-
def game_repository() -> Generator[GameRepository, Any, None]:
13-
with TemporaryDirectory() as temp_dir:
14-
yield GameRepository(temp_dir)
15-
16-
17-
@pytest.fixture
18-
def game() -> Game:
19-
return Game(
20-
game_configuration=GameConfiguration(
21-
NUMBER_OF_COLORS=3,
22-
NUMBER_OF_DOTS=4,
23-
ATTEMPTS_ALLOWED=5,
24-
GAME_MODE=GameMode.PVP,
25-
)
26-
)
27-
28-
298
def test_add(game_repository: GameRepository, game: Game) -> None:
309
uuid = game_repository.add(game)
3110
assert uuid in game_repository
@@ -36,6 +15,12 @@ def test_getitem(game_repository: GameRepository, game: Game) -> None:
3615
assert game_repository[uuid] == game
3716

3817

18+
def test_retrieve_uncached_file(game_repository: GameRepository, game: Game) -> None:
19+
game_repository.io_handler.add("some_uuid", game)
20+
retrieved_game = game_repository["some_uuid"]
21+
assert retrieved_game == game
22+
23+
3924
def test_update_item(game_repository: GameRepository, game: Game) -> None:
4025
uuid = game_repository.add(game)
4126
new_game = Game(
@@ -50,13 +35,23 @@ def test_update_item(game_repository: GameRepository, game: Game) -> None:
5035
assert game_repository[uuid] == new_game
5136

5237

38+
def test_update_item_nonexistent(game_repository: GameRepository, game: Game) -> None:
39+
with pytest.raises(KeyError):
40+
game_repository["nonexistent_uuid"] = game
41+
42+
5343
def test_delitem(game_repository: GameRepository, game: Game) -> None:
5444
uuid = game_repository.add(game)
5545
assert uuid in game_repository
5646
del game_repository[uuid]
5747
assert uuid not in game_repository
5848

5949

50+
def test_delitem_nonexistent(game_repository: GameRepository) -> None:
51+
with pytest.raises(KeyError):
52+
del game_repository["nonexistent_uuid"]
53+
54+
6055
def test_len(game_repository: GameRepository, game: Game) -> None:
6156
assert len(game_repository) == 0
6257
game_repository.add(game)
@@ -68,5 +63,7 @@ def test_len(game_repository: GameRepository, game: Game) -> None:
6863
def test_iter(game_repository: GameRepository, game: Game) -> None:
6964
game_repository.add(game)
7065
game_repository.add(game)
71-
assert all(_game == game_repository[uuid] for uuid, _game in game_repository)
7266
assert len(list(game_repository)) == 2
67+
68+
for uuid, _game in game_repository:
69+
assert _game == game_repository[uuid]
Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,16 @@
22

33
import pytest
44

5-
from mastermind.server.database.enum import GameMode, PlayerRole
6-
from mastermind.server.database.models import Game, GameConfiguration, GameRound
5+
from mastermind.server.database.enum import PlayerRole
6+
from mastermind.server.database.models import Game, GameRound
77
from mastermind.server.services import (
8-
GameboardService,
98
GameEndedException,
109
GameNotStartedException,
1110
GameService,
1211
NoRedoAvailableException,
1312
)
1413

1514

16-
@pytest.fixture
17-
def game() -> Game:
18-
return Game(
19-
game_configuration=GameConfiguration(
20-
NUMBER_OF_COLORS=3,
21-
NUMBER_OF_DOTS=4,
22-
ATTEMPTS_ALLOWED=5,
23-
GAME_MODE=GameMode.PVP,
24-
)
25-
)
26-
27-
28-
@pytest.fixture
29-
def game_service(game: Game) -> GameService:
30-
return GameService(game, GameboardService(game.game_board))
31-
32-
3315
def test_add_round(game_service: GameService, game: Game) -> None:
3416
game_service.add_round((1, 2, 3, 4), (1, 0))
3517
assert game.game_board.game_rounds == deque(

0 commit comments

Comments
 (0)