from pathlib import Path from engine.config import KeyBindings from engine.controls_menu import ControlsMenu def make_menu(): bindings = KeyBindings.load(Path("/nonexistent")) return ControlsMenu(bindings) def test_move_wraps_around_the_action_list(): menu = make_menu() menu.move(-1) assert menu.selected_action() == menu.actions[-1] def test_capture_key_is_ignored_until_rebind_begins(): menu = make_menu() action = menu.selected_action() original = list(menu.keybindings.keys_for_action(action)) applied = menu.capture_key("z") assert applied is False assert menu.keybindings.keys_for_action(action) == original def test_begin_rebind_then_capture_key_rebinds_the_primary_key(): menu = make_menu() menu.selected_index = menu.actions.index("leap") menu.begin_rebind() applied = menu.capture_key("j") assert applied is True assert menu.awaiting_key is False assert menu.keybindings.action_for_key("j") == "leap" assert menu.keybindings.action_for_key(" ") is None # old primary key freed def test_capture_key_rejects_reserved_menu_keys(): menu = make_menu() menu.selected_index = menu.actions.index("leap") menu.begin_rebind() applied = menu.capture_key("Escape") assert applied is False assert menu.awaiting_key is True # still waiting - player can try again def test_cancel_rebind_stops_capturing(): menu = make_menu() menu.begin_rebind() menu.cancel_rebind() assert menu.capture_key("z") is False def test_rebind_steals_the_key_from_whichever_action_had_it(): bindings = KeyBindings.load(Path("/nonexistent")) bindings.rebind("leap", "w") assert bindings.action_for_key("w") == "leap" assert "w" not in bindings.keys_for_action("move_up") def test_save_and_reload_round_trips_a_rebind(tmp_path): bindings = KeyBindings.load(Path("/nonexistent")) bindings.rebind("leap", "j") path = tmp_path / "keybindings.conf" bindings.save(path) reloaded = KeyBindings.load(path) assert reloaded.action_for_key("j") == "leap"