Skip to content

Commit e18189b

Browse files
committed
test(service): move game service's examples to pytest and added more
1 parent dab3a63 commit e18189b

File tree

4 files changed

+94
-34
lines changed

4 files changed

+94
-34
lines changed

src/mastermind/core/models/game_state.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def get_winner(
4141
max_attempts: int,
4242
last_feedback: tuple[int, int],
4343
number_of_dots: int,
44-
) -> Optional[PlayerRole]:
44+
) -> PlayerRole:
4545
"""Determines the winner of the game based on the number of attempts and the last feedback.
4646
4747
Args:

src/mastermind/core/services/game_service.py

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,6 @@ def add_round(self, guess: tuple[int, ...], feedback: tuple[int, int]) -> None:
3535
guess (tuple[int, ...]): A tuple representing the player's current guess.
3636
feedback (tuple[int, int]): A tuple containing the number of correct and misplaced pegs.
3737
38-
Examples:
39-
>>> from mastermind.core.models.game_configuration import GameConfiguration
40-
>>> from mastermind.core.models.game_mode import GameMode
41-
>>> game = Game(game_configuration=GameConfiguration(NUMBER_OF_COLORS=3, NUMBER_OF_DOTS=4, ATTEMPTS_ALLOWED=5, GAME_MODE=GameMode.PVP))
42-
>>> service = GameService(game)
43-
>>> service.add_round((1, 2, 3, 4), (1, 0))
44-
>>> game.game_board.game_rounds
45-
deque([GameRound(GUESS=(1, 2, 3, 4), FEEDBACK=(1, 0))])
46-
4738
Raises:
4839
GameEndedException: When trying to add a round to a game that has ended.
4940
"""
@@ -63,18 +54,6 @@ def add_round(self, guess: tuple[int, ...], feedback: tuple[int, int]) -> None:
6354
def undo(self) -> None:
6455
"""Undo the most recent game round.
6556
66-
Examples:
67-
>>> from mastermind.core.models.game_configuration import GameConfiguration
68-
>>> from mastermind.core.models.game_mode import GameMode
69-
>>> game = Game(game_configuration=GameConfiguration(NUMBER_OF_COLORS=3, NUMBER_OF_DOTS=4, ATTEMPTS_ALLOWED=5, GAME_MODE=GameMode.PVP))
70-
>>> service = GameService(game)
71-
>>> service.add_round((1, 2, 3, 4), (1, 0))
72-
>>> game.game_board.game_rounds
73-
deque([GameRound(GUESS=(1, 2, 3, 4), FEEDBACK=(1, 0))])
74-
>>> service.undo()
75-
>>> game.game_board.game_rounds
76-
deque([])
77-
7857
Raises:
7958
GameNotStartedException: When trying to undo game rounds before the game has started.
8059
GameEndedException: When trying to undo game rounds after the game has ended.
@@ -93,17 +72,6 @@ def undo(self) -> None:
9372
def redo(self) -> None:
9473
"""Restores the most recently undone game round.
9574
96-
Examples:
97-
>>> from mastermind.core.models.game_configuration import GameConfiguration
98-
>>> from mastermind.core.models.game_mode import GameMode
99-
>>> game = Game(game_configuration=GameConfiguration(NUMBER_OF_COLORS=3, NUMBER_OF_DOTS=4, ATTEMPTS_ALLOWED=5, GAME_MODE=GameMode.PVP))
100-
>>> service = GameService(game)
101-
>>> service.add_round((1, 2, 3, 4), (1, 0))
102-
>>> service.undo()
103-
>>> service.redo()
104-
>>> game.game_board.game_rounds
105-
deque([GameRound(GUESS=(1, 2, 3, 4), FEEDBACK=(1, 0))])
106-
10775
Raises:
10876
GameNotStartedException: When trying to redo game rounds before the game has started.
10977
"""

src/mastermind/core/services/gameboard_service.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
from mastermind.core.models.gameboard import GameBoard
66

77

8+
class NoRedoAvailableException(Exception):
9+
pass
10+
11+
812
class GameboardService:
913
"""This class manages the game board and provides methods for adding and undoing game rounds.
1014
@@ -60,7 +64,11 @@ def redo(self) -> None:
6064
[GameRound(GUESS=(1, 2, 3, 4), FEEDBACK=(1, 0)), GameRound(GUESS=(3, 4, 5, 6), FEEDBACK=(2, 1))]
6165
"""
6266

63-
self.game_rounds.append(self.undo_stack.pop())
67+
try:
68+
self.game_rounds.append(self.undo_stack.pop())
69+
70+
except IndexError as e:
71+
raise NoRedoAvailableException("No redo available.") from e
6472

6573
def add_round(self, guess: tuple[int, ...], feedback: tuple[int, int]) -> None:
6674
"""Adds a new game round with the player's guess and corresponding feedback.
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
from collections import deque
2+
3+
import pytest
4+
5+
from mastermind.core.controllers.players import PlayerRole
6+
from mastermind.core.models.game import Game
7+
from mastermind.core.models.game_configuration import GameConfiguration
8+
from mastermind.core.models.game_mode import GameMode
9+
from mastermind.core.models.game_round import GameRound
10+
from mastermind.core.services.game_service import (
11+
GameEndedException,
12+
GameNotStartedException,
13+
GameService,
14+
)
15+
from mastermind.core.services.gameboard_service import NoRedoAvailableException
16+
17+
18+
@pytest.fixture
19+
def game():
20+
return Game(
21+
game_configuration=GameConfiguration(
22+
NUMBER_OF_COLORS=3,
23+
NUMBER_OF_DOTS=4,
24+
ATTEMPTS_ALLOWED=5,
25+
GAME_MODE=GameMode.PVP,
26+
)
27+
)
28+
29+
30+
@pytest.fixture
31+
def game_service(game: Game):
32+
return GameService(game)
33+
34+
35+
def test_add_round(game_service: GameService, game: Game):
36+
game_service.add_round((1, 2, 3, 4), (1, 0))
37+
assert game.game_board.game_rounds == deque(
38+
[GameRound(GUESS=(1, 2, 3, 4), FEEDBACK=(1, 0))]
39+
)
40+
41+
42+
def test_undo(game_service: GameService, game: Game):
43+
game_service.add_round((1, 2, 3, 4), (1, 0))
44+
game_service.undo()
45+
assert game.game_board.game_rounds == deque([])
46+
47+
48+
def test_add_round_with_redo(game_service: GameService, game: Game):
49+
game_service.add_round((1, 2, 3, 4), (1, 0))
50+
game_service.undo()
51+
game_service.redo()
52+
assert game.game_board.game_rounds == deque(
53+
[GameRound(GUESS=(1, 2, 3, 4), FEEDBACK=(1, 0))]
54+
)
55+
56+
57+
def test_add_round_after_end(game_service: GameService, game: Game):
58+
game.game_state.game_started = True
59+
game.game_state.winner = PlayerRole.CODE_SETTER
60+
with pytest.raises(GameEndedException):
61+
game_service.add_round((1, 2, 3, 4), (1, 0))
62+
63+
64+
def test_undo_after_end(game_service: GameService, game: Game):
65+
game.game_state.game_started = True
66+
game.game_state.winner = PlayerRole.CODE_SETTER
67+
with pytest.raises(GameEndedException):
68+
game_service.undo()
69+
70+
71+
def test_undo_before_start(game_service: GameService, game: Game):
72+
with pytest.raises(GameNotStartedException):
73+
game_service.undo()
74+
75+
76+
def test_redo_before_start(game_service: GameService, game: Game):
77+
with pytest.raises(GameNotStartedException):
78+
game_service.redo()
79+
80+
81+
def test_redo_without_undo(game_service: GameService, game: Game):
82+
game_service.add_round((1, 2, 3, 4), (1, 0))
83+
with pytest.raises(NoRedoAvailableException):
84+
game_service.redo()

0 commit comments

Comments
 (0)