Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mscheltienne committed Dec 3, 2024
1 parent 2b8eec1 commit 01056cc
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 10 deletions.
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ style = [
]
test = [
'pytest-cov',
'pytest-randomly',
'pytest-rerunfailures',
'pytest-timeout',
'pytest>=8.0.0',
'stimuli[lsl]',
Expand Down
22 changes: 13 additions & 9 deletions stimuli/keyboard/_keyboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,13 @@ def __repr__(self) -> str:
else:
status = "invalid"
if self._keys is None:
repr_ = f"< {self.__class__.__name__} ({status}) - monitor all keys >"
repr_ = f"<{self.__class__.__name__} ({status}) - monitor all keys>"
else:
repr_ = f"< {self.__class__.__name__} ({status}) - "
repr_ = f"<{self.__class__.__name__} ({status}) - "
if len(self._keys) <= 3:
repr_ += f"monitor {', '.join(self._keys)} >"
repr_ += f"monitor {', '.join(self._keys)}>"
else:
repr_ += f"monitor {len(self._keys)} keys >"
repr_ += f"monitor {len(self._keys)} keys>"
return repr_

def start(self, *, suppress: bool = False) -> Keyboard:
Expand Down Expand Up @@ -136,20 +136,24 @@ def stop(self) -> Keyboard:
warn("The keyboard is not running.")
return self

def get_keys(self) -> list[KeyEvent]:
def get_keys(self) -> list[KeyEvent] | None:
"""Get a list of keys that were pressed since the last call.
Returns
-------
keys : list of KeyEvent
The list of keys that were pressed.
keys : list of KeyEvent | None
The list of keys that were pressed. If the keyboard is not running, None is
returned.
Notes
-----
Note that calling this method will reset the buffer.
"""
with self._lock:
return self._buffer.get()
if self._listener is not None:
with self._lock:
return self._buffer.get()
else:
warn("The keyboard is not running.")

def wait_keys(self, *, timeout: float | None = None) -> KeyEvent | None:
"""Wait until a key is pressed.
Expand Down
56 changes: 56 additions & 0 deletions stimuli/keyboard/tests/test_keyboard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from __future__ import annotations

import pytest
from numpy.testing import assert_allclose
from pynput.keyboard import Controller

from stimuli.keyboard import Keyboard, KeyEvent
from stimuli.time import sleep


@pytest.fixture(scope="module")
def controller() -> Controller:
"""Controller for keyboard, to simulate key press and release.""" # noqa: D401
return Controller()


@pytest.mark.flaky(reruns=10)
def test_keyboard_basic(controller: Controller) -> None:
"""Test basic keyboard functionalities."""
kb = Keyboard().start(suppress=True)
assert isinstance(kb, Keyboard)
controller.press("a")
sleep(0.1)
controller.release("a")
keys = kb.get_keys()
kb.stop()
assert isinstance(keys, list)
assert len(keys) == 1
assert isinstance(keys[0], KeyEvent)
assert keys[0].key == "a"
assert keys[0].press_time is not None
assert keys[0].release_time is not None
assert_allclose(keys[0].release_time - keys[0].press_time, 0.1, atol=0.01)
with pytest.warns(RuntimeWarning, match="keyboard is not running"):
assert kb.get_keys() is None


def test_keyboard_repr() -> None:
"""Test keyboard representation."""
kb = Keyboard()
assert repr(kb) == "<Keyboard (disabled) - monitor all keys>"
kb.start()
assert repr(kb) == "<Keyboard (enabled) - monitor all keks>"
kb.stop()

kb = Keyboard(keys=["a", "b", "c"])
assert repr(kb) == "<Keyboard (disabled) - monitor a, b, c>"
kb.start()
assert repr(kb) == "<Keyboard (enabled) - monitor a, b, c>"
kb.stop()

kb = Keyboard(keys=["a", "b", "c", "d"])
assert repr(kb) == "<Keyboard (disabled) - monitor 4 keys>"
kb.start()
assert repr(kb) == "<Keyboard (enabled) - monitor 4 keys>"
kb.stop()
2 changes: 1 addition & 1 deletion stimuli/trigger/tests/test_lsl.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import pytest


def test_trigger_lsl():
def test_trigger_lsl() -> None:
"""Testing for LSL trigger."""
pytest.importorskip("mne_lsl")

Expand Down

0 comments on commit 01056cc

Please sign in to comment.