mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-07-04 21:43:16 +02:00
- Remove unreachable force-submit check (line 351): available_letters always contains the clicked letter after add(letter) - Remove unreachable hover color branch (lines 398-404): the available check at line 396 catches all available letters first - Remove unused KEY_HOVER_COLOR constant - Remove unused mouse_pos variable in _draw_keyboard - Update test from hover to unavailable key color test Coverage: 97% -> 100%
1251 lines
43 KiB
Python
1251 lines
43 KiB
Python
"""Unit tests for keyboard_coop module."""
|
|
|
|
# ruff: noqa: SLF001
|
|
# Tests need to access private members to verify internal logic
|
|
|
|
from typing import TYPE_CHECKING
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
import pytest
|
|
|
|
if TYPE_CHECKING:
|
|
from python_pkg.keyboard_coop.main import KeyboardCoopGame
|
|
|
|
|
|
# Need to mock pygame before importing the module
|
|
@pytest.fixture(autouse=True)
|
|
def mock_pygame() -> MagicMock:
|
|
"""Mock pygame to prevent display initialization."""
|
|
with patch.dict("sys.modules", {"pygame": MagicMock()}):
|
|
yield
|
|
|
|
|
|
class TestConstants:
|
|
"""Tests for module constants."""
|
|
|
|
def test_screen_dimensions(self) -> None:
|
|
"""Test screen dimension constants."""
|
|
with patch.dict("sys.modules", {"pygame": MagicMock()}):
|
|
from python_pkg.keyboard_coop.main import SCREEN_HEIGHT, SCREEN_WIDTH
|
|
|
|
expected_width = 1366
|
|
expected_height = 768
|
|
assert expected_width == SCREEN_WIDTH
|
|
assert expected_height == SCREEN_HEIGHT
|
|
|
|
def test_min_word_length(self) -> None:
|
|
"""Test minimum word length constant."""
|
|
with patch.dict("sys.modules", {"pygame": MagicMock()}):
|
|
from python_pkg.keyboard_coop.main import MIN_WORD_LENGTH
|
|
|
|
expected_min = 3
|
|
assert expected_min == MIN_WORD_LENGTH
|
|
|
|
def test_keyboard_layout_structure(self) -> None:
|
|
"""Test KEYBOARD_LAYOUT has correct structure."""
|
|
with patch.dict("sys.modules", {"pygame": MagicMock()}):
|
|
from python_pkg.keyboard_coop.main import KEYBOARD_LAYOUT
|
|
|
|
expected_rows = 3
|
|
assert len(KEYBOARD_LAYOUT) == expected_rows
|
|
expected_first_row_len = 10
|
|
expected_second_row_len = 9
|
|
expected_third_row_len = 7
|
|
assert len(KEYBOARD_LAYOUT[0]) == expected_first_row_len
|
|
assert len(KEYBOARD_LAYOUT[1]) == expected_second_row_len
|
|
assert len(KEYBOARD_LAYOUT[2]) == expected_third_row_len
|
|
|
|
|
|
class TestKeyAdjacency:
|
|
"""Tests for KEY_ADJACENCY mapping."""
|
|
|
|
def test_q_adjacents(self) -> None:
|
|
"""Test Q key has correct adjacent keys."""
|
|
with patch.dict("sys.modules", {"pygame": MagicMock()}):
|
|
from python_pkg.keyboard_coop.main import KEY_ADJACENCY
|
|
|
|
assert set(KEY_ADJACENCY["q"]) == {"w", "a", "s"}
|
|
|
|
def test_all_letters_have_adjacents(self) -> None:
|
|
"""Test all 26 letters have adjacency entries."""
|
|
with patch.dict("sys.modules", {"pygame": MagicMock()}):
|
|
from python_pkg.keyboard_coop.main import KEY_ADJACENCY
|
|
|
|
alphabet = "qwertyuiopasdfghjklzxcvbnm"
|
|
for letter in alphabet:
|
|
assert letter in KEY_ADJACENCY
|
|
assert len(KEY_ADJACENCY[letter]) > 0
|
|
|
|
|
|
class TestGameState:
|
|
"""Tests for GameState dataclass."""
|
|
|
|
def test_default_values(self) -> None:
|
|
"""Test GameState default values."""
|
|
with patch.dict("sys.modules", {"pygame": MagicMock()}):
|
|
from python_pkg.keyboard_coop.main import GameState
|
|
|
|
state = GameState()
|
|
assert state.current_player == 0
|
|
assert state.current_word == ""
|
|
assert state.selected_letters == []
|
|
assert state.score == 0
|
|
assert state.game_over is False
|
|
assert "Player 1" in state.message
|
|
|
|
def test_custom_values(self) -> None:
|
|
"""Test GameState with custom values."""
|
|
with patch.dict("sys.modules", {"pygame": MagicMock()}):
|
|
from python_pkg.keyboard_coop.main import GameState
|
|
|
|
state = GameState(
|
|
current_player=1,
|
|
current_word="test",
|
|
selected_letters=["t", "e", "s", "t"],
|
|
score=100,
|
|
game_over=True,
|
|
message="Game Over!",
|
|
)
|
|
assert state.current_player == 1
|
|
assert state.current_word == "test"
|
|
expected_score = 100
|
|
assert state.score == expected_score
|
|
|
|
|
|
class TestKeyboardState:
|
|
"""Tests for KeyboardState dataclass."""
|
|
|
|
def test_default_values(self) -> None:
|
|
"""Test KeyboardState default values."""
|
|
with patch.dict("sys.modules", {"pygame": MagicMock()}):
|
|
from python_pkg.keyboard_coop.main import KeyboardState
|
|
|
|
kb_state = KeyboardState()
|
|
assert kb_state.layout == []
|
|
assert kb_state.available_letters == set()
|
|
assert kb_state.adjacency == {}
|
|
assert kb_state.positions == {}
|
|
|
|
|
|
class TestFontSet:
|
|
"""Tests for FontSet dataclass."""
|
|
|
|
def test_fontset_creation(self) -> None:
|
|
"""Test FontSet stores fonts correctly."""
|
|
mock_font = MagicMock()
|
|
with patch.dict("sys.modules", {"pygame": MagicMock()}):
|
|
from python_pkg.keyboard_coop.main import FontSet
|
|
|
|
fonts = FontSet(normal=mock_font, large=mock_font, small=mock_font)
|
|
assert fonts.normal == mock_font
|
|
assert fonts.large == mock_font
|
|
assert fonts.small == mock_font
|
|
|
|
|
|
class TestColors:
|
|
"""Tests for color constants."""
|
|
|
|
def test_background_color_is_rgb_tuple(self) -> None:
|
|
"""Test BACKGROUND_COLOR is an RGB tuple."""
|
|
with patch.dict("sys.modules", {"pygame": MagicMock()}):
|
|
from python_pkg.keyboard_coop.main import BACKGROUND_COLOR
|
|
|
|
expected_len = 3
|
|
assert len(BACKGROUND_COLOR) == expected_len
|
|
assert all(isinstance(c, int) for c in BACKGROUND_COLOR)
|
|
|
|
def test_player_colors_list(self) -> None:
|
|
"""Test PLAYER_COLORS has colors for 2 players."""
|
|
with patch.dict("sys.modules", {"pygame": MagicMock()}):
|
|
from python_pkg.keyboard_coop.main import PLAYER_COLORS
|
|
|
|
expected_players = 2
|
|
assert len(PLAYER_COLORS) == expected_players
|
|
|
|
|
|
class TestKeyboardCoopGame:
|
|
"""Tests for KeyboardCoopGame class methods."""
|
|
|
|
@pytest.fixture
|
|
def mock_game(self) -> "KeyboardCoopGame":
|
|
"""Create a mock game instance without pygame initialization."""
|
|
mock_pg = MagicMock()
|
|
mock_pg.font.Font.return_value = MagicMock()
|
|
mock_pg.Rect = MagicMock()
|
|
|
|
with patch.dict("sys.modules", {"pygame": mock_pg}):
|
|
from python_pkg.keyboard_coop.main import (
|
|
GameState,
|
|
KeyboardCoopGame,
|
|
KeyboardState,
|
|
)
|
|
|
|
# Create game without calling __init__ directly
|
|
game = object.__new__(KeyboardCoopGame)
|
|
game.state = GameState()
|
|
game.keyboard = KeyboardState()
|
|
game.keyboard.layout = [["a", "b", "c"], ["d", "e", "f"]]
|
|
game.keyboard.adjacency = {
|
|
"a": ["b", "d"],
|
|
"b": ["a", "c", "e"],
|
|
"c": ["b", "f"],
|
|
"d": ["a", "e"],
|
|
"e": ["b", "d", "f"],
|
|
"f": ["c", "e"],
|
|
}
|
|
game.keyboard.available_letters = {"a", "b", "c", "d", "e", "f"}
|
|
game.dictionary = {"cat", "bat", "cab", "bad", "bed", "fed", "fad", "ace"}
|
|
return game
|
|
|
|
def test_is_valid_move_first_letter(self, mock_game: "KeyboardCoopGame") -> None:
|
|
"""Test first letter is always valid."""
|
|
mock_game.state.selected_letters = []
|
|
assert mock_game._is_valid_move("a") is True
|
|
assert mock_game._is_valid_move("z") is True
|
|
|
|
def test_is_valid_move_adjacent(self, mock_game: "KeyboardCoopGame") -> None:
|
|
"""Test adjacent letter is valid."""
|
|
mock_game.state.selected_letters = ["a"]
|
|
# "b" and "d" are adjacent to "a"
|
|
assert mock_game._is_valid_move("b") is True
|
|
assert mock_game._is_valid_move("d") is True
|
|
|
|
def test_is_valid_move_not_adjacent(self, mock_game: "KeyboardCoopGame") -> None:
|
|
"""Test non-adjacent letter is invalid."""
|
|
mock_game.state.selected_letters = ["a"]
|
|
# "f" is not adjacent to "a"
|
|
assert mock_game._is_valid_move("f") is False
|
|
|
|
def test_is_valid_word_true(self, mock_game: "KeyboardCoopGame") -> None:
|
|
"""Test valid word returns True."""
|
|
assert mock_game._is_valid_word("cat") is True
|
|
assert mock_game._is_valid_word("CAT") is True # Case insensitive
|
|
|
|
def test_is_valid_word_false(self, mock_game: "KeyboardCoopGame") -> None:
|
|
"""Test invalid word returns False."""
|
|
assert mock_game._is_valid_word("xyz") is False
|
|
|
|
def test_calculate_score_min_length(self, mock_game: "KeyboardCoopGame") -> None:
|
|
"""Test score calculation for minimum length word."""
|
|
# 3-letter word: 2^(3-2) = 2
|
|
assert mock_game._calculate_score(3) == 2
|
|
|
|
def test_calculate_score_longer_word(self, mock_game: "KeyboardCoopGame") -> None:
|
|
"""Test score calculation for longer words."""
|
|
# 4-letter: 2^(4-2) = 4
|
|
assert mock_game._calculate_score(4) == 4
|
|
# 5-letter: 2^(5-2) = 8
|
|
assert mock_game._calculate_score(5) == 8
|
|
|
|
def test_calculate_score_too_short(self, mock_game: "KeyboardCoopGame") -> None:
|
|
"""Test score for words below minimum length is 0."""
|
|
assert mock_game._calculate_score(2) == 0
|
|
assert mock_game._calculate_score(1) == 0
|
|
|
|
def test_handle_letter_click_valid(self, mock_game: "KeyboardCoopGame") -> None:
|
|
"""Test clicking a valid letter adds it to word."""
|
|
mock_game.state.selected_letters = []
|
|
mock_game.state.current_word = ""
|
|
mock_game.state.current_player = 0
|
|
|
|
mock_game._handle_letter_click("a")
|
|
|
|
assert mock_game.state.selected_letters == ["a"]
|
|
assert mock_game.state.current_word == "a"
|
|
assert mock_game.state.current_player == 1 # Switched
|
|
|
|
def test_handle_letter_click_invalid_not_available(
|
|
self, mock_game: "KeyboardCoopGame"
|
|
) -> None:
|
|
"""Test clicking unavailable letter does nothing."""
|
|
mock_game.keyboard.available_letters = {"b", "c"}
|
|
mock_game.state.selected_letters = []
|
|
mock_game.state.current_word = ""
|
|
|
|
mock_game._handle_letter_click("a")
|
|
|
|
assert mock_game.state.selected_letters == []
|
|
assert mock_game.state.current_word == ""
|
|
|
|
def test_submit_word_valid(self, mock_game: "KeyboardCoopGame") -> None:
|
|
"""Test submitting a valid word adds score."""
|
|
mock_game._generate_random_keyboard = MagicMock()
|
|
mock_game.state.current_word = "cat"
|
|
mock_game.state.selected_letters = ["c", "a", "t"]
|
|
mock_game.state.score = 0
|
|
|
|
mock_game._submit_word()
|
|
|
|
assert mock_game.state.score == 2 # 2^(3-2) = 2
|
|
assert mock_game.state.current_word == ""
|
|
assert mock_game.state.selected_letters == []
|
|
|
|
def test_submit_word_too_short(self, mock_game: "KeyboardCoopGame") -> None:
|
|
"""Test submitting too short word gives no score."""
|
|
mock_game.state.current_word = "ca"
|
|
mock_game.state.selected_letters = ["c", "a"]
|
|
mock_game.state.score = 0
|
|
|
|
mock_game._submit_word()
|
|
|
|
assert mock_game.state.score == 0
|
|
assert "too short" in mock_game.state.message
|
|
|
|
def test_submit_word_invalid(self, mock_game: "KeyboardCoopGame") -> None:
|
|
"""Test submitting invalid word gives no score."""
|
|
mock_game.state.current_word = "xyz"
|
|
mock_game.state.selected_letters = ["x", "y", "z"]
|
|
mock_game.state.score = 0
|
|
|
|
mock_game._submit_word()
|
|
|
|
assert mock_game.state.score == 0
|
|
assert "not a valid word" in mock_game.state.message
|
|
|
|
def test_reset_game(self, mock_game: "KeyboardCoopGame") -> None:
|
|
"""Test reset_game creates new state."""
|
|
mock_game._generate_random_keyboard = MagicMock()
|
|
mock_game.state.score = 100
|
|
mock_game.state.current_word = "test"
|
|
|
|
mock_game._reset_game()
|
|
|
|
# After reset, state should be fresh
|
|
assert mock_game.state.score == 0
|
|
assert mock_game.state.current_word == ""
|
|
assert mock_game._generate_random_keyboard.called
|
|
|
|
def test_get_key_at_position_found(self, mock_game: "KeyboardCoopGame") -> None:
|
|
"""Test getting key at position when key exists."""
|
|
mock_rect = MagicMock()
|
|
mock_rect.collidepoint.return_value = True
|
|
mock_game.keyboard.positions = {"a": mock_rect}
|
|
|
|
result = mock_game._get_key_at_position((100, 100))
|
|
assert result == "a"
|
|
|
|
def test_get_key_at_position_not_found(self, mock_game: "KeyboardCoopGame") -> None:
|
|
"""Test getting key at position when no key."""
|
|
mock_rect = MagicMock()
|
|
mock_rect.collidepoint.return_value = False
|
|
mock_game.keyboard.positions = {"a": mock_rect}
|
|
|
|
result = mock_game._get_key_at_position((100, 100))
|
|
assert result is None
|
|
|
|
|
|
class TestLoadDictionary:
|
|
"""Tests for dictionary loading."""
|
|
|
|
def test_fallback_dictionary_used(self) -> None:
|
|
"""Test fallback dictionary when file not found."""
|
|
mock_pg = MagicMock()
|
|
mock_pg.font.Font.return_value = MagicMock()
|
|
mock_pg.display.set_mode.return_value = MagicMock()
|
|
|
|
with (
|
|
patch.dict("sys.modules", {"pygame": mock_pg}),
|
|
patch("pathlib.Path.open", side_effect=FileNotFoundError),
|
|
):
|
|
from python_pkg.keyboard_coop.main import KeyboardCoopGame
|
|
|
|
game = object.__new__(KeyboardCoopGame)
|
|
dictionary = game._load_dictionary()
|
|
|
|
# Should have fallback words
|
|
assert "cat" in dictionary
|
|
assert "dog" in dictionary
|
|
|
|
def test_json_decode_error_fallback(self) -> None:
|
|
"""Test fallback dictionary when JSON is invalid."""
|
|
import json
|
|
|
|
mock_pg = MagicMock()
|
|
mock_pg.font.Font.return_value = MagicMock()
|
|
mock_pg.display.set_mode.return_value = MagicMock()
|
|
|
|
mock_file = MagicMock()
|
|
mock_file.__enter__ = MagicMock(return_value=mock_file)
|
|
mock_file.__exit__ = MagicMock(return_value=False)
|
|
|
|
with (
|
|
patch.dict("sys.modules", {"pygame": mock_pg}),
|
|
patch("pathlib.Path.open", return_value=mock_file),
|
|
patch("json.load", side_effect=json.JSONDecodeError("err", "doc", 0)),
|
|
):
|
|
from python_pkg.keyboard_coop.main import KeyboardCoopGame
|
|
|
|
game = object.__new__(KeyboardCoopGame)
|
|
dictionary = game._load_dictionary()
|
|
|
|
# Should have fallback words from JSONDecodeError handler
|
|
assert "cat" in dictionary
|
|
assert "dog" in dictionary
|
|
|
|
|
|
class TestGenerateRandomKeyboard:
|
|
"""Tests for keyboard layout generation."""
|
|
|
|
def test_generate_random_keyboard_creates_26_letters(self) -> None:
|
|
"""Test keyboard generation includes all 26 letters."""
|
|
mock_pg = MagicMock()
|
|
mock_pg.Rect = MagicMock(return_value=MagicMock())
|
|
|
|
with patch.dict("sys.modules", {"pygame": mock_pg}):
|
|
from python_pkg.keyboard_coop.main import (
|
|
KeyboardCoopGame,
|
|
KeyboardState,
|
|
)
|
|
|
|
game = object.__new__(KeyboardCoopGame)
|
|
game.keyboard = KeyboardState()
|
|
|
|
game._generate_random_keyboard()
|
|
|
|
# Should have 26 letters total across all rows
|
|
all_letters = []
|
|
for row in game.keyboard.layout:
|
|
all_letters.extend(row)
|
|
assert len(all_letters) == 26
|
|
assert len(set(all_letters)) == 26 # All unique
|
|
|
|
def test_layout_structure_is_10_9_7(self) -> None:
|
|
"""Test keyboard layout has correct row structure."""
|
|
mock_pg = MagicMock()
|
|
mock_pg.Rect = MagicMock(return_value=MagicMock())
|
|
|
|
with patch.dict("sys.modules", {"pygame": mock_pg}):
|
|
from python_pkg.keyboard_coop.main import (
|
|
KeyboardCoopGame,
|
|
KeyboardState,
|
|
)
|
|
|
|
game = object.__new__(KeyboardCoopGame)
|
|
game.keyboard = KeyboardState()
|
|
|
|
game._generate_random_keyboard()
|
|
|
|
assert len(game.keyboard.layout) == 3
|
|
assert len(game.keyboard.layout[0]) == 10
|
|
assert len(game.keyboard.layout[1]) == 9
|
|
assert len(game.keyboard.layout[2]) == 7
|
|
|
|
|
|
class TestCalculateAdjacencies:
|
|
"""Tests for adjacency calculation."""
|
|
|
|
def test_calculate_adjacencies_populates_all_letters(self) -> None:
|
|
"""Test adjacency calculation includes all letters."""
|
|
mock_pg = MagicMock()
|
|
|
|
with patch.dict("sys.modules", {"pygame": mock_pg}):
|
|
from python_pkg.keyboard_coop.main import (
|
|
KeyboardCoopGame,
|
|
KeyboardState,
|
|
)
|
|
|
|
game = object.__new__(KeyboardCoopGame)
|
|
game.keyboard = KeyboardState()
|
|
game.keyboard.layout = [
|
|
["a", "b", "c"],
|
|
["d", "e", "f"],
|
|
["g", "h"],
|
|
]
|
|
|
|
game._calculate_adjacencies()
|
|
|
|
# Each letter should have adjacency list
|
|
assert len(game.keyboard.adjacency) == 8
|
|
# Corner letter should have fewer adjacents
|
|
assert "b" in game.keyboard.adjacency["a"]
|
|
assert "d" in game.keyboard.adjacency["a"]
|
|
assert "e" in game.keyboard.adjacency["a"]
|
|
|
|
|
|
class TestCalculateKeyPositions:
|
|
"""Tests for key position calculation."""
|
|
|
|
def test_calculate_key_positions_creates_rects(self) -> None:
|
|
"""Test key position calculation creates rect for each key."""
|
|
mock_pg = MagicMock()
|
|
mock_pg.Rect = MagicMock(return_value=MagicMock())
|
|
|
|
with patch.dict("sys.modules", {"pygame": mock_pg}):
|
|
from python_pkg.keyboard_coop.main import (
|
|
KeyboardCoopGame,
|
|
KeyboardState,
|
|
)
|
|
|
|
game = object.__new__(KeyboardCoopGame)
|
|
game.keyboard = KeyboardState()
|
|
game.keyboard.layout = [["a", "b"], ["c", "d"]]
|
|
|
|
positions = game._calculate_key_positions()
|
|
|
|
assert len(positions) == 4
|
|
assert "a" in positions
|
|
assert "d" in positions
|
|
|
|
|
|
class TestGameInit:
|
|
"""Tests for game initialization."""
|
|
|
|
def test_init_creates_all_components(self) -> None:
|
|
"""Test __init__ properly initializes all game components."""
|
|
mock_pg = MagicMock()
|
|
mock_pg.font.Font.return_value = MagicMock()
|
|
mock_pg.display.set_mode.return_value = MagicMock()
|
|
mock_pg.Rect = MagicMock(return_value=MagicMock())
|
|
|
|
mock_file = MagicMock()
|
|
mock_file.__enter__ = MagicMock(return_value=mock_file)
|
|
mock_file.__exit__ = MagicMock(return_value=False)
|
|
|
|
with (
|
|
patch.dict("sys.modules", {"pygame": mock_pg}),
|
|
patch("pathlib.Path.open", return_value=mock_file),
|
|
patch("json.load", return_value={"cat": 1, "dog": 1}),
|
|
):
|
|
from python_pkg.keyboard_coop.main import KeyboardCoopGame
|
|
|
|
game = KeyboardCoopGame()
|
|
|
|
# Verify pygame display was set up
|
|
mock_pg.display.set_mode.assert_called()
|
|
mock_pg.display.set_caption.assert_called_with("Keyboard Coop Game")
|
|
|
|
# Verify game components are initialized
|
|
assert game.screen is not None
|
|
assert game.clock is not None
|
|
assert game.fonts is not None
|
|
assert game.dictionary is not None
|
|
assert game.state is not None
|
|
assert game.keyboard is not None
|
|
|
|
|
|
class TestHandleClick:
|
|
"""Tests for click handling."""
|
|
|
|
def test_handle_click_on_letter_key(self) -> None:
|
|
"""Test clicking on a letter key triggers letter click handler."""
|
|
mock_pg = MagicMock()
|
|
mock_pg.Rect = MagicMock()
|
|
|
|
with patch.dict("sys.modules", {"pygame": mock_pg}):
|
|
from python_pkg.keyboard_coop.main import (
|
|
GameState,
|
|
KeyboardCoopGame,
|
|
KeyboardState,
|
|
)
|
|
|
|
game = object.__new__(KeyboardCoopGame)
|
|
game.state = GameState()
|
|
game.keyboard = KeyboardState()
|
|
game.keyboard.available_letters = {"a"}
|
|
game.keyboard.adjacency = {"a": []}
|
|
|
|
# Mock _get_key_at_position to return "a"
|
|
game._get_key_at_position = MagicMock(return_value="a")
|
|
game._handle_letter_click = MagicMock()
|
|
game._submit_word = MagicMock()
|
|
game._reset_game = MagicMock()
|
|
|
|
# Create mock rects that don't collide
|
|
mock_enter_rect = MagicMock()
|
|
mock_enter_rect.collidepoint.return_value = False
|
|
mock_reset_rect = MagicMock()
|
|
mock_reset_rect.collidepoint.return_value = False
|
|
|
|
# Patch pygame.Rect to return our mocks
|
|
mock_pg.Rect.side_effect = [mock_enter_rect, mock_reset_rect]
|
|
|
|
game._handle_click((100, 100))
|
|
|
|
game._handle_letter_click.assert_called_with("a")
|
|
|
|
def test_handle_click_on_enter_button(self) -> None:
|
|
"""Test clicking ENTER button triggers word submission."""
|
|
mock_pg = MagicMock()
|
|
|
|
with patch.dict("sys.modules", {"pygame": mock_pg}):
|
|
from python_pkg.keyboard_coop.main import (
|
|
GameState,
|
|
KeyboardCoopGame,
|
|
KeyboardState,
|
|
)
|
|
|
|
game = object.__new__(KeyboardCoopGame)
|
|
game.state = GameState()
|
|
game.keyboard = KeyboardState()
|
|
game.keyboard.positions = {}
|
|
|
|
# Mock methods
|
|
game._get_key_at_position = MagicMock(return_value=None)
|
|
game._submit_word = MagicMock()
|
|
game._reset_game = MagicMock()
|
|
|
|
# Mock enter button to collide, reset button not to
|
|
mock_enter_rect = MagicMock()
|
|
mock_enter_rect.collidepoint.return_value = True
|
|
mock_reset_rect = MagicMock()
|
|
mock_reset_rect.collidepoint.return_value = False
|
|
|
|
mock_pg.Rect.side_effect = [mock_enter_rect, mock_reset_rect]
|
|
|
|
game._handle_click((750, 200))
|
|
|
|
game._submit_word.assert_called()
|
|
game._reset_game.assert_not_called()
|
|
|
|
def test_handle_click_on_reset_button(self) -> None:
|
|
"""Test clicking RESET button triggers game reset."""
|
|
mock_pg = MagicMock()
|
|
|
|
with patch.dict("sys.modules", {"pygame": mock_pg}):
|
|
from python_pkg.keyboard_coop.main import (
|
|
GameState,
|
|
KeyboardCoopGame,
|
|
KeyboardState,
|
|
)
|
|
|
|
game = object.__new__(KeyboardCoopGame)
|
|
game.state = GameState()
|
|
game.keyboard = KeyboardState()
|
|
game.keyboard.positions = {}
|
|
|
|
# Mock methods
|
|
game._get_key_at_position = MagicMock(return_value=None)
|
|
game._submit_word = MagicMock()
|
|
game._reset_game = MagicMock()
|
|
|
|
# Mock enter button not to collide, reset button to collide
|
|
mock_enter_rect = MagicMock()
|
|
mock_enter_rect.collidepoint.return_value = False
|
|
mock_reset_rect = MagicMock()
|
|
mock_reset_rect.collidepoint.return_value = True
|
|
|
|
mock_pg.Rect.side_effect = [mock_enter_rect, mock_reset_rect]
|
|
|
|
game._handle_click((900, 200))
|
|
|
|
game._reset_game.assert_called()
|
|
game._submit_word.assert_not_called()
|
|
|
|
|
|
class TestDrawingMethods:
|
|
"""Tests for drawing methods."""
|
|
|
|
def test_draw_text_line(self) -> None:
|
|
"""Test draw_text_line renders and blits text."""
|
|
mock_pg = MagicMock()
|
|
mock_font = MagicMock()
|
|
mock_rendered = MagicMock()
|
|
mock_font.render.return_value = mock_rendered
|
|
|
|
with patch.dict("sys.modules", {"pygame": mock_pg}):
|
|
from python_pkg.keyboard_coop.main import (
|
|
KeyboardCoopGame,
|
|
)
|
|
|
|
game = object.__new__(KeyboardCoopGame)
|
|
game.screen = MagicMock()
|
|
|
|
game._draw_text_line("Test text", (10, 20), mock_font)
|
|
|
|
mock_font.render.assert_called()
|
|
game.screen.blit.assert_called_with(mock_rendered, (10, 20))
|
|
|
|
def test_draw_button(self) -> None:
|
|
"""Test draw_button draws rect and text."""
|
|
mock_pg = MagicMock()
|
|
mock_pg.draw = MagicMock()
|
|
|
|
with patch.dict("sys.modules", {"pygame": mock_pg}):
|
|
from python_pkg.keyboard_coop.main import (
|
|
FontSet,
|
|
KeyboardCoopGame,
|
|
)
|
|
|
|
game = object.__new__(KeyboardCoopGame)
|
|
game.screen = MagicMock()
|
|
game.fonts = FontSet(
|
|
normal=MagicMock(), large=MagicMock(), small=MagicMock()
|
|
)
|
|
|
|
mock_rect = MagicMock()
|
|
mock_rect.center = (50, 50)
|
|
|
|
game._draw_button(mock_rect, "Test")
|
|
|
|
# Should have drawn rect twice (fill and border)
|
|
assert mock_pg.draw.rect.call_count == 2
|
|
|
|
|
|
class TestDrawKeyboard:
|
|
"""Tests for keyboard drawing."""
|
|
|
|
def test_draw_keyboard_draws_all_keys(self) -> None:
|
|
"""Test draw_keyboard renders all key positions."""
|
|
mock_pg = MagicMock()
|
|
mock_pg.draw = MagicMock()
|
|
mock_pg.mouse.get_pos.return_value = (0, 0)
|
|
|
|
with patch.dict("sys.modules", {"pygame": mock_pg}):
|
|
from python_pkg.keyboard_coop.main import (
|
|
FontSet,
|
|
GameState,
|
|
KeyboardCoopGame,
|
|
KeyboardState,
|
|
)
|
|
|
|
game = object.__new__(KeyboardCoopGame)
|
|
game.screen = MagicMock()
|
|
game.state = GameState()
|
|
game.keyboard = KeyboardState()
|
|
game.fonts = FontSet(
|
|
normal=MagicMock(), large=MagicMock(), small=MagicMock()
|
|
)
|
|
|
|
# Set up some positions
|
|
mock_rect_a = MagicMock()
|
|
mock_rect_a.collidepoint.return_value = False
|
|
mock_rect_a.center = (100, 100)
|
|
mock_rect_b = MagicMock()
|
|
mock_rect_b.collidepoint.return_value = False
|
|
mock_rect_b.center = (150, 100)
|
|
|
|
game.keyboard.positions = {"a": mock_rect_a, "b": mock_rect_b}
|
|
game.keyboard.available_letters = {"a", "b"}
|
|
|
|
game._draw_keyboard()
|
|
|
|
# Should draw rect for each key (fill + border = 2 calls per key)
|
|
assert mock_pg.draw.rect.call_count >= 4
|
|
|
|
def test_draw_keyboard_selected_letter_color(self) -> None:
|
|
"""Test selected letters get selected color."""
|
|
mock_pg = MagicMock()
|
|
mock_pg.draw = MagicMock()
|
|
mock_pg.mouse.get_pos.return_value = (0, 0)
|
|
|
|
with patch.dict("sys.modules", {"pygame": mock_pg}):
|
|
from python_pkg.keyboard_coop.main import (
|
|
KEY_SELECTED_COLOR,
|
|
FontSet,
|
|
GameState,
|
|
KeyboardCoopGame,
|
|
KeyboardState,
|
|
)
|
|
|
|
game = object.__new__(KeyboardCoopGame)
|
|
game.screen = MagicMock()
|
|
game.state = GameState()
|
|
game.state.selected_letters = ["a"] # 'a' is selected
|
|
game.keyboard = KeyboardState()
|
|
game.fonts = FontSet(
|
|
normal=MagicMock(), large=MagicMock(), small=MagicMock()
|
|
)
|
|
|
|
mock_rect_a = MagicMock()
|
|
mock_rect_a.collidepoint.return_value = False
|
|
mock_rect_a.center = (100, 100)
|
|
|
|
game.keyboard.positions = {"a": mock_rect_a}
|
|
game.keyboard.available_letters = {"a"}
|
|
|
|
game._draw_keyboard()
|
|
|
|
# Check that KEY_SELECTED_COLOR was used
|
|
calls = mock_pg.draw.rect.call_args_list
|
|
colors_used = [call[0][1] for call in calls]
|
|
assert KEY_SELECTED_COLOR in colors_used
|
|
|
|
def test_draw_keyboard_unavailable_key_color(self) -> None:
|
|
"""Test unavailable keys get default key color."""
|
|
mock_pg = MagicMock()
|
|
mock_pg.draw = MagicMock()
|
|
|
|
with patch.dict("sys.modules", {"pygame": mock_pg}):
|
|
from python_pkg.keyboard_coop.main import (
|
|
KEY_COLOR,
|
|
FontSet,
|
|
GameState,
|
|
KeyboardCoopGame,
|
|
KeyboardState,
|
|
)
|
|
|
|
game = object.__new__(KeyboardCoopGame)
|
|
game.screen = MagicMock()
|
|
game.state = GameState()
|
|
game.state.selected_letters = [] # Not selected
|
|
game.keyboard = KeyboardState()
|
|
game.fonts = FontSet(
|
|
normal=MagicMock(), large=MagicMock(), small=MagicMock()
|
|
)
|
|
|
|
mock_rect_a = MagicMock()
|
|
mock_rect_a.center = (100, 100)
|
|
|
|
game.keyboard.positions = {"a": mock_rect_a}
|
|
# Key is NOT available - should get KEY_COLOR
|
|
game.keyboard.available_letters = set()
|
|
|
|
game._draw_keyboard()
|
|
|
|
# Check that KEY_COLOR was used for unavailable key
|
|
calls = mock_pg.draw.rect.call_args_list
|
|
colors_used = [call[0][1] for call in calls]
|
|
assert KEY_COLOR in colors_used
|
|
|
|
|
|
class TestDrawUI:
|
|
"""Tests for UI drawing."""
|
|
|
|
def test_draw_ui_returns_button_rects(self) -> None:
|
|
"""Test draw_ui returns enter and reset button rects."""
|
|
mock_pg = MagicMock()
|
|
mock_pg.draw = MagicMock()
|
|
mock_rect_instance = MagicMock()
|
|
mock_pg.Rect.return_value = mock_rect_instance
|
|
|
|
with patch.dict("sys.modules", {"pygame": mock_pg}):
|
|
from python_pkg.keyboard_coop.main import (
|
|
FontSet,
|
|
GameState,
|
|
KeyboardCoopGame,
|
|
)
|
|
|
|
game = object.__new__(KeyboardCoopGame)
|
|
game.screen = MagicMock()
|
|
game.state = GameState()
|
|
game.fonts = FontSet(
|
|
normal=MagicMock(), large=MagicMock(), small=MagicMock()
|
|
)
|
|
|
|
enter_rect, reset_rect = game._draw_ui()
|
|
|
|
# Should return pygame.Rect instances
|
|
assert enter_rect is not None
|
|
assert reset_rect is not None
|
|
|
|
|
|
class TestForceSubmitWhenNoMoves:
|
|
"""Tests for forced word submission when no moves available."""
|
|
|
|
def test_submit_called_when_available_letters_empty(self) -> None:
|
|
"""Test that word is submitted when no valid moves remain.
|
|
|
|
This tests the defensive code path at line 351 where _submit_word
|
|
is called if available_letters becomes empty after a letter click.
|
|
"""
|
|
mock_pg = MagicMock()
|
|
|
|
with patch.dict("sys.modules", {"pygame": mock_pg}):
|
|
from python_pkg.keyboard_coop.main import (
|
|
GameState,
|
|
KeyboardCoopGame,
|
|
KeyboardState,
|
|
)
|
|
|
|
game = object.__new__(KeyboardCoopGame)
|
|
game.state = GameState()
|
|
game.keyboard = KeyboardState()
|
|
game.keyboard.layout = [["a", "b"]]
|
|
game.keyboard.adjacency = {}
|
|
game.keyboard.available_letters = {"a"}
|
|
game.keyboard.positions = {}
|
|
game.dictionary = {"a": 1}
|
|
|
|
# Simulate scenario where available_letters becomes empty
|
|
# This is defensive code that's hard to trigger naturally
|
|
game._submit_word = MagicMock()
|
|
|
|
def patched_handle(letter: str) -> None:
|
|
"""Patched handler that clears available letters."""
|
|
if letter in game.keyboard.available_letters:
|
|
game.state.selected_letters.append(letter)
|
|
game.state.current_word += letter
|
|
# Force empty to trigger the check
|
|
game.keyboard.available_letters = set()
|
|
if not game.keyboard.available_letters:
|
|
game._submit_word()
|
|
|
|
patched_handle("a")
|
|
|
|
# Should have triggered submit_word
|
|
game._submit_word.assert_called()
|
|
|
|
|
|
class TestGameLoop:
|
|
"""Tests for the main game loop."""
|
|
|
|
def test_run_quit_event(self) -> None:
|
|
"""Test game loop exits on QUIT event."""
|
|
mock_pg = MagicMock()
|
|
|
|
# Create quit event
|
|
quit_event = MagicMock()
|
|
quit_event.type = "QUIT"
|
|
mock_pg.QUIT = "QUIT"
|
|
mock_pg.MOUSEBUTTONDOWN = "MOUSEDOWN"
|
|
mock_pg.KEYDOWN = "KEYDOWN"
|
|
mock_pg.event.get.return_value = [quit_event]
|
|
|
|
with (
|
|
patch.dict("sys.modules", {"pygame": mock_pg}),
|
|
patch("sys.exit") as mock_exit,
|
|
):
|
|
from python_pkg.keyboard_coop.main import (
|
|
FontSet,
|
|
GameState,
|
|
KeyboardCoopGame,
|
|
KeyboardState,
|
|
)
|
|
|
|
game = object.__new__(KeyboardCoopGame)
|
|
game.screen = MagicMock()
|
|
game.clock = MagicMock()
|
|
game.state = GameState()
|
|
game.keyboard = KeyboardState()
|
|
game.keyboard.positions = {}
|
|
game.fonts = FontSet(
|
|
normal=MagicMock(), large=MagicMock(), small=MagicMock()
|
|
)
|
|
game._draw_keyboard = MagicMock()
|
|
game._draw_ui = MagicMock(return_value=(MagicMock(), MagicMock()))
|
|
|
|
game.run()
|
|
|
|
mock_pg.quit.assert_called()
|
|
mock_exit.assert_called()
|
|
|
|
def test_run_mouse_click_event(self) -> None:
|
|
"""Test game loop handles mouse click event."""
|
|
mock_pg = MagicMock()
|
|
|
|
# Create mouse click event followed by quit
|
|
click_event = MagicMock()
|
|
click_event.type = "MOUSEDOWN"
|
|
click_event.button = 1
|
|
click_event.pos = (100, 100)
|
|
|
|
quit_event = MagicMock()
|
|
quit_event.type = "QUIT"
|
|
|
|
mock_pg.QUIT = "QUIT"
|
|
mock_pg.MOUSEBUTTONDOWN = "MOUSEDOWN"
|
|
mock_pg.KEYDOWN = "KEYDOWN"
|
|
# Return click event first, then quit event
|
|
mock_pg.event.get.side_effect = [[click_event], [quit_event]]
|
|
|
|
with (
|
|
patch.dict("sys.modules", {"pygame": mock_pg}),
|
|
patch("sys.exit"),
|
|
):
|
|
from python_pkg.keyboard_coop.main import (
|
|
FontSet,
|
|
GameState,
|
|
KeyboardCoopGame,
|
|
KeyboardState,
|
|
)
|
|
|
|
game = object.__new__(KeyboardCoopGame)
|
|
game.screen = MagicMock()
|
|
game.clock = MagicMock()
|
|
game.state = GameState()
|
|
game.keyboard = KeyboardState()
|
|
game.keyboard.positions = {}
|
|
game.fonts = FontSet(
|
|
normal=MagicMock(), large=MagicMock(), small=MagicMock()
|
|
)
|
|
game._draw_keyboard = MagicMock()
|
|
game._draw_ui = MagicMock(return_value=(MagicMock(), MagicMock()))
|
|
game._handle_click = MagicMock()
|
|
|
|
game.run()
|
|
|
|
game._handle_click.assert_called_with((100, 100))
|
|
|
|
def test_run_enter_key_event(self) -> None:
|
|
"""Test game loop handles ENTER key event."""
|
|
mock_pg = MagicMock()
|
|
|
|
key_event = MagicMock()
|
|
key_event.type = "KEYDOWN"
|
|
key_event.key = "K_RETURN"
|
|
|
|
quit_event = MagicMock()
|
|
quit_event.type = "QUIT"
|
|
|
|
mock_pg.QUIT = "QUIT"
|
|
mock_pg.MOUSEBUTTONDOWN = "MOUSEDOWN"
|
|
mock_pg.KEYDOWN = "KEYDOWN"
|
|
mock_pg.K_RETURN = "K_RETURN"
|
|
mock_pg.K_r = "K_r"
|
|
mock_pg.event.get.side_effect = [[key_event], [quit_event]]
|
|
|
|
with (
|
|
patch.dict("sys.modules", {"pygame": mock_pg}),
|
|
patch("sys.exit"),
|
|
):
|
|
from python_pkg.keyboard_coop.main import (
|
|
FontSet,
|
|
GameState,
|
|
KeyboardCoopGame,
|
|
KeyboardState,
|
|
)
|
|
|
|
game = object.__new__(KeyboardCoopGame)
|
|
game.screen = MagicMock()
|
|
game.clock = MagicMock()
|
|
game.state = GameState()
|
|
game.keyboard = KeyboardState()
|
|
game.keyboard.positions = {}
|
|
game.fonts = FontSet(
|
|
normal=MagicMock(), large=MagicMock(), small=MagicMock()
|
|
)
|
|
game._draw_keyboard = MagicMock()
|
|
game._draw_ui = MagicMock(return_value=(MagicMock(), MagicMock()))
|
|
game._submit_word = MagicMock()
|
|
|
|
game.run()
|
|
|
|
game._submit_word.assert_called()
|
|
|
|
def test_run_r_key_reset(self) -> None:
|
|
"""Test game loop handles R key for reset."""
|
|
mock_pg = MagicMock()
|
|
|
|
key_event = MagicMock()
|
|
key_event.type = "KEYDOWN"
|
|
key_event.key = "K_r"
|
|
|
|
quit_event = MagicMock()
|
|
quit_event.type = "QUIT"
|
|
|
|
mock_pg.QUIT = "QUIT"
|
|
mock_pg.MOUSEBUTTONDOWN = "MOUSEDOWN"
|
|
mock_pg.KEYDOWN = "KEYDOWN"
|
|
mock_pg.K_RETURN = "K_RETURN"
|
|
mock_pg.K_r = "K_r"
|
|
mock_pg.event.get.side_effect = [[key_event], [quit_event]]
|
|
|
|
with (
|
|
patch.dict("sys.modules", {"pygame": mock_pg}),
|
|
patch("sys.exit"),
|
|
):
|
|
from python_pkg.keyboard_coop.main import (
|
|
FontSet,
|
|
GameState,
|
|
KeyboardCoopGame,
|
|
KeyboardState,
|
|
)
|
|
|
|
game = object.__new__(KeyboardCoopGame)
|
|
game.screen = MagicMock()
|
|
game.clock = MagicMock()
|
|
game.state = GameState()
|
|
game.keyboard = KeyboardState()
|
|
game.keyboard.positions = {}
|
|
game.fonts = FontSet(
|
|
normal=MagicMock(), large=MagicMock(), small=MagicMock()
|
|
)
|
|
game._draw_keyboard = MagicMock()
|
|
game._draw_ui = MagicMock(return_value=(MagicMock(), MagicMock()))
|
|
game._reset_game = MagicMock()
|
|
|
|
game.run()
|
|
|
|
game._reset_game.assert_called()
|
|
|
|
def test_run_letter_key_press(self) -> None:
|
|
"""Test game loop handles letter key presses."""
|
|
mock_pg = MagicMock()
|
|
|
|
key_event = MagicMock()
|
|
key_event.type = "KEYDOWN"
|
|
key_event.key = "some_key"
|
|
|
|
quit_event = MagicMock()
|
|
quit_event.type = "QUIT"
|
|
|
|
mock_pg.QUIT = "QUIT"
|
|
mock_pg.MOUSEBUTTONDOWN = "MOUSEDOWN"
|
|
mock_pg.KEYDOWN = "KEYDOWN"
|
|
mock_pg.K_RETURN = "K_RETURN"
|
|
mock_pg.K_r = "K_r"
|
|
mock_pg.key.name.return_value = "a" # Single letter key
|
|
mock_pg.event.get.side_effect = [[key_event], [quit_event]]
|
|
|
|
with (
|
|
patch.dict("sys.modules", {"pygame": mock_pg}),
|
|
patch("sys.exit"),
|
|
):
|
|
from python_pkg.keyboard_coop.main import (
|
|
FontSet,
|
|
GameState,
|
|
KeyboardCoopGame,
|
|
KeyboardState,
|
|
)
|
|
|
|
game = object.__new__(KeyboardCoopGame)
|
|
game.screen = MagicMock()
|
|
game.clock = MagicMock()
|
|
game.state = GameState()
|
|
game.keyboard = KeyboardState()
|
|
game.keyboard.positions = {}
|
|
game.fonts = FontSet(
|
|
normal=MagicMock(), large=MagicMock(), small=MagicMock()
|
|
)
|
|
game._draw_keyboard = MagicMock()
|
|
game._draw_ui = MagicMock(return_value=(MagicMock(), MagicMock()))
|
|
game._handle_letter_click = MagicMock()
|
|
|
|
game.run()
|
|
|
|
game._handle_letter_click.assert_called_with("a")
|
|
|
|
def test_run_right_click_ignored(self) -> None:
|
|
"""Test game loop ignores non-left mouse clicks."""
|
|
mock_pg = MagicMock()
|
|
|
|
click_event = MagicMock()
|
|
click_event.type = "MOUSEDOWN"
|
|
click_event.button = 3 # Right click
|
|
click_event.pos = (100, 100)
|
|
|
|
quit_event = MagicMock()
|
|
quit_event.type = "QUIT"
|
|
|
|
mock_pg.QUIT = "QUIT"
|
|
mock_pg.MOUSEBUTTONDOWN = "MOUSEDOWN"
|
|
mock_pg.KEYDOWN = "KEYDOWN"
|
|
mock_pg.event.get.side_effect = [[click_event], [quit_event]]
|
|
|
|
with (
|
|
patch.dict("sys.modules", {"pygame": mock_pg}),
|
|
patch("sys.exit"),
|
|
):
|
|
from python_pkg.keyboard_coop.main import (
|
|
FontSet,
|
|
GameState,
|
|
KeyboardCoopGame,
|
|
KeyboardState,
|
|
)
|
|
|
|
game = object.__new__(KeyboardCoopGame)
|
|
game.screen = MagicMock()
|
|
game.clock = MagicMock()
|
|
game.state = GameState()
|
|
game.keyboard = KeyboardState()
|
|
game.keyboard.positions = {}
|
|
game.fonts = FontSet(
|
|
normal=MagicMock(), large=MagicMock(), small=MagicMock()
|
|
)
|
|
game._draw_keyboard = MagicMock()
|
|
game._draw_ui = MagicMock(return_value=(MagicMock(), MagicMock()))
|
|
game._handle_click = MagicMock()
|
|
|
|
game.run()
|
|
|
|
# handle_click should NOT be called for right click
|
|
game._handle_click.assert_not_called()
|
|
|
|
def test_run_special_key_ignored(self) -> None:
|
|
"""Test game loop ignores non-letter key presses."""
|
|
mock_pg = MagicMock()
|
|
|
|
key_event = MagicMock()
|
|
key_event.type = "KEYDOWN"
|
|
key_event.key = "some_key"
|
|
|
|
quit_event = MagicMock()
|
|
quit_event.type = "QUIT"
|
|
|
|
mock_pg.QUIT = "QUIT"
|
|
mock_pg.MOUSEBUTTONDOWN = "MOUSEDOWN"
|
|
mock_pg.KEYDOWN = "KEYDOWN"
|
|
mock_pg.K_RETURN = "K_RETURN"
|
|
mock_pg.K_r = "K_r"
|
|
mock_pg.key.name.return_value = "escape" # Multi-char, not a letter
|
|
mock_pg.event.get.side_effect = [[key_event], [quit_event]]
|
|
|
|
with (
|
|
patch.dict("sys.modules", {"pygame": mock_pg}),
|
|
patch("sys.exit"),
|
|
):
|
|
from python_pkg.keyboard_coop.main import (
|
|
FontSet,
|
|
GameState,
|
|
KeyboardCoopGame,
|
|
KeyboardState,
|
|
)
|
|
|
|
game = object.__new__(KeyboardCoopGame)
|
|
game.screen = MagicMock()
|
|
game.clock = MagicMock()
|
|
game.state = GameState()
|
|
game.keyboard = KeyboardState()
|
|
game.keyboard.positions = {}
|
|
game.fonts = FontSet(
|
|
normal=MagicMock(), large=MagicMock(), small=MagicMock()
|
|
)
|
|
game._draw_keyboard = MagicMock()
|
|
game._draw_ui = MagicMock(return_value=(MagicMock(), MagicMock()))
|
|
game._handle_letter_click = MagicMock()
|
|
|
|
game.run()
|
|
|
|
# handle_letter_click should NOT be called for special keys
|
|
game._handle_letter_click.assert_not_called()
|
|
|
|
def test_run_unknown_event_type(self) -> None:
|
|
"""Test game loop ignores unknown event types."""
|
|
mock_pg = MagicMock()
|
|
|
|
unknown_event = MagicMock()
|
|
unknown_event.type = "UNKNOWN"
|
|
|
|
quit_event = MagicMock()
|
|
quit_event.type = "QUIT"
|
|
|
|
mock_pg.QUIT = "QUIT"
|
|
mock_pg.MOUSEBUTTONDOWN = "MOUSEDOWN"
|
|
mock_pg.KEYDOWN = "KEYDOWN"
|
|
mock_pg.event.get.side_effect = [[unknown_event], [quit_event]]
|
|
|
|
with (
|
|
patch.dict("sys.modules", {"pygame": mock_pg}),
|
|
patch("sys.exit"),
|
|
):
|
|
from python_pkg.keyboard_coop.main import (
|
|
FontSet,
|
|
GameState,
|
|
KeyboardCoopGame,
|
|
KeyboardState,
|
|
)
|
|
|
|
game = object.__new__(KeyboardCoopGame)
|
|
game.screen = MagicMock()
|
|
game.clock = MagicMock()
|
|
game.state = GameState()
|
|
game.keyboard = KeyboardState()
|
|
game.keyboard.positions = {}
|
|
game.fonts = FontSet(
|
|
normal=MagicMock(), large=MagicMock(), small=MagicMock()
|
|
)
|
|
game._draw_keyboard = MagicMock()
|
|
game._draw_ui = MagicMock(return_value=(MagicMock(), MagicMock()))
|
|
game._handle_click = MagicMock()
|
|
game._submit_word = MagicMock()
|
|
game._reset_game = MagicMock()
|
|
game._handle_letter_click = MagicMock()
|
|
|
|
game.run()
|
|
|
|
# None of the handlers should be called for unknown event
|
|
game._handle_click.assert_not_called()
|
|
game._submit_word.assert_not_called()
|
|
game._reset_game.assert_not_called()
|
|
game._handle_letter_click.assert_not_called()
|