199 lines
7.9 KiB
Python
199 lines
7.9 KiB
Python
from engine.config import KeyBindings
|
|
from engine.gamepad import DEFAULT_GAMEPAD_BINDINGS, GamepadBindings, GamepadState
|
|
from engine.input import InputState
|
|
|
|
|
|
def test_move_key_sets_pending_move_and_updates_facing():
|
|
input_state = InputState()
|
|
input_state.handle_event({"event_type": "key_down", "key": "d"})
|
|
assert input_state.consume_move() == (1, 0, 0)
|
|
assert input_state.facing == (1, 0, 0)
|
|
assert input_state.consume_move() is None # consumed
|
|
|
|
|
|
def test_leap_key_uses_last_facing_direction():
|
|
input_state = InputState()
|
|
input_state.handle_event({"event_type": "key_down", "key": "w"})
|
|
input_state.consume_move()
|
|
input_state.handle_event({"event_type": "key_down", "key": " "})
|
|
assert input_state.consume_leap() == (0, -1, 0)
|
|
assert input_state.consume_leap() is None
|
|
|
|
|
|
def test_leap_key_before_any_move_uses_default_facing():
|
|
input_state = InputState()
|
|
input_state.handle_event({"event_type": "key_down", "key": " "})
|
|
assert input_state.consume_leap() == (0, 1, 0)
|
|
|
|
|
|
def test_key_up_events_are_ignored_for_movement():
|
|
input_state = InputState()
|
|
input_state.handle_event({"event_type": "key_up", "key": "d"})
|
|
assert input_state.consume_move() is None
|
|
|
|
|
|
def test_held_key_contributes_to_current_move_vector():
|
|
input_state = InputState()
|
|
assert input_state.current_move_vector() == (0.0, 0.0, 0.0)
|
|
input_state.handle_event({"event_type": "key_down", "key": "d"})
|
|
assert input_state.current_move_vector() == (1.0, 0.0, 0.0)
|
|
|
|
|
|
def test_releasing_a_held_key_removes_its_contribution():
|
|
input_state = InputState()
|
|
input_state.handle_event({"event_type": "key_down", "key": "d"})
|
|
input_state.handle_event({"event_type": "key_up", "key": "d"})
|
|
assert input_state.current_move_vector() == (0.0, 0.0, 0.0)
|
|
|
|
|
|
def test_holding_two_keys_combines_into_a_diagonal_vector():
|
|
input_state = InputState()
|
|
input_state.handle_event({"event_type": "key_down", "key": "d"})
|
|
input_state.handle_event({"event_type": "key_down", "key": "s"})
|
|
assert input_state.current_move_vector() == (1.0, 1.0, 0.0)
|
|
|
|
|
|
def test_opposite_held_keys_cancel_out():
|
|
input_state = InputState()
|
|
input_state.handle_event({"event_type": "key_down", "key": "d"})
|
|
input_state.handle_event({"event_type": "key_down", "key": "a"})
|
|
assert input_state.current_move_vector() == (0.0, 0.0, 0.0)
|
|
|
|
|
|
def test_block_key_is_a_held_state_not_a_one_shot():
|
|
input_state = InputState()
|
|
assert input_state.is_blocking is False
|
|
input_state.handle_event({"event_type": "key_down", "key": "b"})
|
|
assert input_state.is_blocking is True
|
|
input_state.handle_event({"event_type": "key_up", "key": "b"})
|
|
assert input_state.is_blocking is False
|
|
|
|
|
|
def test_mouse_left_click_activates_right_hand():
|
|
input_state = InputState()
|
|
input_state.handle_event({"event_type": "pointer_down", "button": 0, "modifiers": ()})
|
|
assert input_state.consume_hand_activation() == "right_hand"
|
|
assert input_state.consume_hand_activation() is None
|
|
|
|
|
|
def test_mouse_right_click_activates_left_hand():
|
|
input_state = InputState()
|
|
input_state.handle_event({"event_type": "pointer_down", "button": 2, "modifiers": ()})
|
|
assert input_state.consume_hand_activation() == "left_hand"
|
|
|
|
|
|
def test_shift_plus_mouse_click_activates_the_second_hand_pair():
|
|
input_state = InputState()
|
|
input_state.handle_event({"event_type": "pointer_down", "button": 0, "modifiers": ("Shift",)})
|
|
assert input_state.consume_hand_activation() == "right_hand_2"
|
|
|
|
|
|
def test_pointer_move_tracks_position():
|
|
input_state = InputState()
|
|
assert input_state.pointer_pos is None
|
|
input_state.handle_event({"event_type": "pointer_move", "x": 12.5, "y": 34.0})
|
|
assert input_state.pointer_pos == (12.5, 34.0)
|
|
|
|
|
|
def test_unbound_key_is_ignored():
|
|
input_state = InputState()
|
|
input_state.handle_event({"event_type": "key_down", "key": "q"})
|
|
assert input_state.consume_move() is None
|
|
assert input_state.consume_leap() is None
|
|
|
|
|
|
def test_custom_keybindings_are_respected():
|
|
bindings = KeyBindings({"move_up": ["j"]})
|
|
input_state = InputState(bindings)
|
|
input_state.handle_event({"event_type": "key_down", "key": "j"})
|
|
assert input_state.consume_move() == (0, -1, 0)
|
|
|
|
|
|
def test_numkey_1_selects_ability_bar_slot_0():
|
|
input_state = InputState()
|
|
input_state.handle_event({"event_type": "key_down", "key": "1"})
|
|
assert input_state.consume_ability_select() == 0
|
|
assert input_state.consume_ability_select() is None # consumed
|
|
|
|
|
|
def test_numkey_0_selects_ability_bar_slot_9():
|
|
input_state = InputState()
|
|
input_state.handle_event({"event_type": "key_down", "key": "0"})
|
|
assert input_state.consume_ability_select() == 9
|
|
|
|
|
|
def test_all_ten_numkeys_map_to_distinct_slots():
|
|
input_state = InputState()
|
|
seen = set()
|
|
for key in "1234567890":
|
|
input_state.handle_event({"event_type": "key_down", "key": key})
|
|
seen.add(input_state.consume_ability_select())
|
|
assert seen == set(range(10))
|
|
|
|
|
|
# --- gamepad -------------------------------------------------------------------------------
|
|
|
|
|
|
def test_gamepad_left_stick_drives_current_move_vector():
|
|
input_state = InputState()
|
|
bindings = GamepadBindings(dict(DEFAULT_GAMEPAD_BINDINGS))
|
|
input_state.apply_gamepad_state(GamepadState(axes=[0.8, -0.5, 0, 0, 0, 0]), bindings)
|
|
assert input_state.current_move_vector() == (0.8, -0.5, 0.0)
|
|
|
|
|
|
def test_gamepad_stick_within_deadzone_contributes_nothing():
|
|
input_state = InputState()
|
|
bindings = GamepadBindings(dict(DEFAULT_GAMEPAD_BINDINGS))
|
|
input_state.apply_gamepad_state(GamepadState(axes=[0.05, -0.05, 0, 0, 0, 0]), bindings)
|
|
assert input_state.current_move_vector() == (0.0, 0.0, 0.0)
|
|
|
|
|
|
def test_gamepad_stick_adds_to_held_keyboard_movement():
|
|
input_state = InputState()
|
|
input_state.handle_event({"event_type": "key_down", "key": "d"}) # move_right: (1, 0, 0)
|
|
bindings = GamepadBindings(dict(DEFAULT_GAMEPAD_BINDINGS))
|
|
input_state.apply_gamepad_state(GamepadState(axes=[0.5, 0, 0, 0, 0, 0]), bindings)
|
|
assert input_state.current_move_vector() == (1.5, 0.0, 0.0)
|
|
|
|
|
|
def test_gamepad_button_press_triggers_bound_action():
|
|
input_state = InputState()
|
|
bindings = GamepadBindings(dict(DEFAULT_GAMEPAD_BINDINGS))
|
|
input_state.apply_gamepad_state(GamepadState(buttons={"gp_a": True}), bindings) # gp_a -> leap
|
|
assert input_state.consume_leap() == input_state.facing
|
|
|
|
|
|
def test_gamepad_block_is_held_not_one_shot():
|
|
input_state = InputState()
|
|
bindings = GamepadBindings(dict(DEFAULT_GAMEPAD_BINDINGS))
|
|
input_state.apply_gamepad_state(GamepadState(buttons={"gp_left_bumper": True}), bindings)
|
|
assert input_state.is_blocking is True
|
|
input_state.apply_gamepad_state(GamepadState(buttons={"gp_left_bumper": False}), bindings)
|
|
assert input_state.is_blocking is False
|
|
|
|
|
|
def test_gamepad_trigger_press_activates_bound_hand():
|
|
input_state = InputState()
|
|
bindings = GamepadBindings(dict(DEFAULT_GAMEPAD_BINDINGS))
|
|
axes = [0.0] * 6
|
|
axes[4] = 0.9 # left trigger -> gp_left_trigger -> activate_left_hand_2
|
|
input_state.apply_gamepad_state(GamepadState(axes=axes), bindings)
|
|
assert input_state.consume_hand_activation() == "left_hand_2"
|
|
|
|
|
|
def test_gamepad_holding_a_button_across_frames_does_not_refire():
|
|
input_state = InputState()
|
|
bindings = GamepadBindings(dict(DEFAULT_GAMEPAD_BINDINGS))
|
|
input_state.apply_gamepad_state(GamepadState(buttons={"gp_a": True}), bindings)
|
|
input_state.consume_leap()
|
|
input_state.apply_gamepad_state(GamepadState(buttons={"gp_a": True}), bindings) # still held
|
|
assert input_state.consume_leap() is None # no new leap queued on the second frame
|
|
|
|
|
|
def test_gamepad_unbound_button_is_ignored():
|
|
input_state = InputState()
|
|
bindings = GamepadBindings(dict(DEFAULT_GAMEPAD_BINDINGS))
|
|
input_state.apply_gamepad_state(GamepadState(buttons={"gp_guide": True}), bindings)
|
|
assert input_state.consume_leap() is None
|
|
assert input_state.consume_hand_activation() is None
|