terminal/tests.lisp
defpackage#:luv.terminal.tests
:use#:cl#:rove
:local-nicknames
#:ghostty#:luv.ghostty
#:terminal#:luv.terminal
in-package#:luv.terminal.tests
defmacrowith-pty-test`
ghostty:with-terminal
,terminal:columns40:rows6
let
,devicenil
unwind-protect
when,device
terminal:close-pty-device,device
defunpty-terminal-text
device
defunsend-canvas-key
devicekey&optionalcharacter
terminal:send-pty-device-canvas-key-eventdevice
make-instance'luv:canvas-key-press-event:timestamp0:key-namekey:charactercharacter:unshifted-charactercharacter
defunwait-for-terminal-text
deviceneedle&key
timeout1.0
deftestpty-child-output-and-input-drive-one-terminal
with-pty-test
deviceghostty-terminal:program"/bin/sh":arguments
list"-c""printf 'term:%s\\r\\nready\\r\\n' \"$TERM\"; IFS= read -r line; printf 'got:%s\\r\\n' \"$line\""
terminal:send-pty-device-textdevice
formatnil"hello~%"
ok
eq:exited
let
text
pty-terminal-textdevice
ok
search"ready"text
ok
search"term:xterm-256color"text
ok
search"got:hello"text
ok
null
deftestpty-echo-reaches-the-terminal-before-enter
with-pty-test
deviceghostty-terminal:program"/bin/sh":arguments
list"-c""IFS= read -r line"
terminal:send-pty-device-textdevice"visible-before-enter"
ok
ok
eq:running
deftestpty-child-owns-a-controlling-terminal
with-pty-test
deviceghostty-terminal:program"/bin/sh":arguments
list"-c""test -c /dev/tty && printf 'controlling-tty-ok\\r\\n' > /dev/tty"
ok
eq:exited
ok
zerop
ok
deftestghostty-query-responses-return-through-the-pty
let*
python"python3"
script
formatnil"import os, termios, tty~%old = termios.tcgetattr(0)~%tty.setraw(0)~%os.write(1, b'\\x1b[6n')~%reply = b''~%while not reply.endswith(b'R'):~% reply += os.read(0, 1)~%termios.tcsetattr(0, termios.TCSANOW, old)~%os.write(1, b'query-ok:' + reply.hex().encode() + b'\\r\\n')~%"
with-pty-test
deviceghostty-terminal:programpython:arguments
list"-c"script
ok
eq:exited
ok
ok
null
deftestportable-canvas-keys-reach-the-pty-child
with-pty-test
deviceghostty-terminal:program"/bin/sh":arguments
list"-c""printf 'key-ready\r\n'; IFS= read -r line; printf 'key:%s\r\n' \"$line\""
send-canvas-keydevice:h#\h
send-canvas-keydevice:i#\i
send-canvas-keydevice:return#\Return
ok
eq:exited
let
text
pty-terminal-textdevice
ok
search"key-ready"text
ok
search"key:hi"text
ok
null
deftestresize-coordinates-the-kernel-pty-and-ghostty-grid
with-pty-test
deviceghostty-terminal:program"/bin/sh":arguments
list"-c""IFS= read -r line; stty size"
terminal:resize-pty-devicedevice429:cell-width-pixels8:cell-height-pixels16
terminal:send-pty-device-textdevice
formatnil"size~%"
ok
eq:exited
multiple-value-bind
columnsrows
ok
ok
ok
ok
null
deftestclosing-a-running-device-releases-only-its-pty
with-pty-test
deviceghostty-terminal:program"/bin/sh":arguments
list"-c""printf 'waiting\\r\\n'; sleep 30"
ok
ok
eq:closed
ok
not
sb-thread:thread-alive-p
luv.terminal::pty-device-threaddevice
ok
ghostty:terminal-open-pghostty-terminal
ok
ok
defmacro with-pty-test
((device terminal &rest open-arguments) &body body)defclass terminal
An explicitly owned libghostty-vt terminal.
defmacro with-terminal
((variable &rest initargs) &body body)defun open-pty-device
(terminal &key
(program (or (uiop:getenv "SHELL") "/bin/sh"))
arguments directory environment
(term "xterm-256color") on-output)Start PROGRAM under a PTY whose output drives TERMINAL. The device owns its child, PTY stream, IO thread, and Ghostty response route; it does not own TERMINAL. All terminal mutation and PTY traffic are serialized by the device's worker. Use CALL-WITH-PTY-DEVICE-TERMINAL for renderer-side snapshot work which must…
defun close-pty-device
(device &key (timeout 2.0))defun pty-terminal-text
(device)defun call-with-pty-device-terminal
(device function)defun terminal-text
(terminal)defun send-canvas-key
(device key &optional character)defun send-pty-device-canvas-key-event
(device event)defun wait-for-terminal-text
(device needle &key (timeout 1.0))define-arithmetic-operator +
Addition over compatible quantities.
define-arithmetic-operator *
Multiplication and scalar scaling.
define-arithmetic-operator =
Test whether two compatible scalars are equal.
define-arithmetic-operator >=
Test whether one compatible scalar is at least another.
defun send-pty-device-text
(device text)defun wait-for-pty-device
(device &key (timeout 5.0))defun pty-device-condition
(device)defun pty-device-state
(device)defun pty-device-exit-code
(device)defun resize-pty-device
(device columns rows &key (cell-width-pixels 0) (cell-height-pixels 0))defun terminal-size
(terminal)define-arithmetic-operator not
Logical negation of one test or raw truth value.
defun terminal-open-p
(terminal)defun write-terminal
(terminal text)
The device owns the child and descriptor, not the semantic terminal.