+
+
+PLAYBOOK: tuple[str, ...] = (
+ '<',
+ '>/help',
+ '<commands available in this window:',
+ '< /help ',
+ '< /list ',
+ '< /prompt_enter ',
+ '< /quit ',
+ '< /window TOWARDS',
+ '< /window.history.scroll DIRECTION',
+ '< /window.paste ',
+ '< /window.prompt.backspace ',
+ '< /window.prompt.move_cursor DIRECTION',
+ '< /window.prompt.scroll DIRECTION',
+ '>/list',
+ '<windows available via /window:',
+ '< 0) :start',
+ '>/quit',
+ '<'
+)
+
+
+class TestTerminal(QueueMixin, TerminalInterface):
+ 'Collects keypresses from string queue, otherwise mostly dummy.'
+
+ def __init__(self, **kwargs) -> None:
+ super().__init__(**kwargs)
+ self._q_keypresses: SimpleQueue = SimpleQueue()
+
+ @contextmanager
+ def setup(self) -> Generator:
+ with Loop(iterator=self._get_keypresses(), _q_out=self._q_out):
+ yield self
+
+ def flush(self) -> None:
+ pass
+
+ def calc_geometry(self) -> None:
+ self.size = _YX(0, 0)
+
+ def wrap(self, line: str) -> list[str]:
+ return []
+
+ def write(self,
+ msg: str = '',
+ start_y: Optional[int] = None,
+ attribute: Optional[str] = None,
+ padding: bool = True
+ ) -> None:
+ pass
+
+ def _get_keypresses(self) -> Iterator[Optional[TuiEvent]]:
+ while True:
+ try:
+ to_yield = self._q_keypresses.get(timeout=0.1)
+ except QueueEmpty:
+ break
+ yield TuiEvent.affector('handle_keyboard_event'
+ ).kw(typed_in=to_yield)
+
+
+class TestTui(BaseTui):
+ 'Collects keypresses via TestTerminal from PLAYBOOK, compares log results.'
+
+ def __init__(self, **kwargs) -> None:
+ super().__init__(**kwargs)
+ self._test_idx = 0
+ assert isinstance(self._term, TestTerminal)
+ self._q_keypresses = self._term._q_keypresses
+ self._log('')
+
+ def _log(self, msg: str, **kwargs) -> None:
+ entry = PLAYBOOK[self._test_idx]
+ direction, expected = entry[0], entry[1:]
+ assert direction == '<'
+ assert expected == msg, (self._test_idx, expected, msg)
+ super()._log(msg, **kwargs)
+ while True:
+ self._test_idx += 1
+ entry = PLAYBOOK[self._test_idx]
+ direction, msg = entry[0], entry[1:]
+ if direction == '>':
+ for c in msg:
+ self._q_keypresses.put(c)
+ self._q_keypresses.put('KEY_ENTER')
+ else:
+ break