Files
mice/tests/test_keybindings.py
T
enne2 c7ed24483d Add comprehensive test suite for game mechanics and level handling
- Introduced `test_final_level_flow.py` to validate final level transitions and game end scenarios.
- Created `test_game_over_flow.py` to ensure game over conditions trigger correctly based on rat counts.
- Implemented `test_keybindings.py` to verify keybinding configurations and their context-specific actions.
- Developed `test_level_editor.py` to assess level editor functionalities and layout computations.
- Added `test_level_io.py` for testing level data serialization and deserialization.
- Established `test_loop_logic_parity.py` to ensure consistent game state across multiple simulation runs.
- Created `test_non_regression.py` to simulate game behavior and capture states for future verification.
- Implemented `test_verify.py` to compare current game states against a golden master for regression detection.
2026-05-19 22:18:43 +02:00

160 lines
4.7 KiB
Python

#!/usr/bin/env python3
import unittest
from pathlib import Path
from unittest.mock import MagicMock
from engine import controls
class DummyBindings(controls.KeyBindings):
def __init__(self, game=None):
if game is None:
game = MagicMock()
game.menu_up = lambda: None
game.menu_down = lambda: None
game.menu_left = lambda: None
game.menu_right = lambda: None
game.reset_game = lambda: None
super().__init__(game)
def spawn_rat(self):
pass
def toggle_audio(self):
pass
def toggle_full_screen(self):
pass
def start_scrolling(self, direction):
pass
def stop_scrolling(self):
pass
def spawn_new_bomb(self):
pass
def spawn_new_nuclear_bomb(self):
pass
def spawn_new_mine(self):
pass
def spawn_new_gas(self):
pass
def spawn_gas(self, parent_id=None):
pass
def toggle_pause(self):
pass
def reset_game(self):
pass
def quit_game(self):
pass
def menu_up(self):
pass
def menu_down(self):
pass
def menu_left(self):
pass
def menu_right(self):
pass
class KeybindingProfileTests(unittest.TestCase):
def test_shipped_profiles_expose_all_weapon_actions(self):
dummy = DummyBindings()
conf_dir = Path(__file__).resolve().parent / "conf"
weapon_actions = {
"spawn_new_bomb",
"spawn_new_nuclear_bomb",
"spawn_new_mine",
"spawn_new_gas",
}
for config_path in sorted(conf_dir.glob("keybindings*.json")) + sorted(conf_dir.glob("keybindings*.yaml")):
bindings = controls._load_bindings_from_file(config_path)
validated = dummy._validate_bindings(bindings, config_path)
game_bindings = validated.get("keybinding_game", {})
self.assertTrue(game_bindings, f"missing keybinding_game in {config_path.name}")
actions = set(game_bindings.values())
self.assertTrue(
weapon_actions.issubset(actions),
f"incomplete weapon bindings in {config_path.name}: {sorted(actions)}",
)
def test_shipped_profiles_define_level_dialog_bindings(self):
dummy = DummyBindings()
conf_dir = Path(__file__).resolve().parent / "conf"
required_sections = {
"keybinding_start_menu", # Corrected from level_intro since we removed it
"keybinding_level_clear",
"keybinding_defeat",
"keybinding_run_complete",
}
for config_path in sorted(conf_dir.glob("keybindings*.json")) + sorted(conf_dir.glob("keybindings*.yaml")):
bindings = controls._load_bindings_from_file(config_path)
validated = dummy._validate_bindings(bindings, config_path)
for section_name in required_sections:
section = validated.get(section_name, {})
self.assertTrue(section, f"missing {section_name} in {config_path.name}")
values = set(section.values())
self.assertIn("reset_game", values, f"missing confirm binding in {section_name} for {config_path.name}")
self.assertIn("quit_game", values, f"missing quit binding in {section_name} for {config_path.name}")
def test_trigger_uses_start_menu_context(self):
game = MagicMock()
dummy = DummyBindings(game)
calls = []
# Override action_dispatcher for testing
dummy.action_dispatcher["reset_game"] = lambda: calls.append("reset")
dummy.action_dispatcher["quit_game"] = lambda: calls.append("quit")
dummy.bindings = {
"keybinding_start_menu": {"keydown_Return": "reset_game"},
}
game.game_status = "start_menu"
game.menu_screen = "start"
game.game_end = (False, None)
dummy.trigger("keydown_Return")
self.assertEqual(calls, ["reset"])
def test_trigger_uses_level_clear_context(self):
game = MagicMock()
dummy = DummyBindings(game)
calls = []
dummy.action_dispatcher["reset_game"] = lambda: calls.append("reset")
dummy.action_dispatcher["quit_game"] = lambda: calls.append("quit")
dummy.bindings = {
"keybinding_level_clear": {"keydown_Return": "reset_game"},
"keybinding_paused": {"keydown_Return": "quit_game"},
}
game.game_status = "paused"
game.menu_screen = None
game.game_end = (True, "level_clear")
dummy.trigger("keydown_Return")
self.assertEqual(calls, ["reset"])
if __name__ == "__main__":
unittest.main()