1.1--- a/lisp/lib/cli/tests.lisp Sun Mar 17 18:29:37 2024 -0400
1.2+++ b/lisp/lib/cli/tests.lisp Sun Mar 17 22:21:29 2024 -0400
1.3@@ -1,11 +1,198 @@
1.4 (defpackage :cli/tests
1.5- (:use :cl :std :rt :cli :cli/progress :cli/spark :cli/repl :cli/ansi :cli/prompt))
1.6+ (:use :cl :std :rt :cli :cli/shell :cli/progress :cli/spark :cli/repl :cli/ansi :cli/prompt))
1.7
1.8 (in-package :cli/tests)
1.9 (defsuite :cli)
1.10 (in-suite :cli)
1.11
1.12-(deftest ansi () )
1.13+(defun ansi-t01 ()
1.14+ (erase)
1.15+ (cursor-position 0 0)
1.16+ (princ "0")
1.17+ (cursor-position 2 2)
1.18+ (princ "1")
1.19+ (cursor-position 5 15)
1.20+ (princ "test")
1.21+ (cursor-position 10 15)
1.22+ (force-output)
1.23+ (let ((a (read-line)))
1.24+ (cursor-position 12 15)
1.25+ (princ a)
1.26+ (force-output)))
1.27+
1.28+(defun ansi-t02 ()
1.29+ (print "normal")
1.30+ (.sgr 1)
1.31+ (print "bold")
1.32+ (.sgr 4)
1.33+ (print "bold underline")
1.34+ (.sgr 7)
1.35+ (print "bold underline reverse")
1.36+ (.sgr 22)
1.37+ (print "underline reverse")
1.38+ (.sgr 24)
1.39+ (print "reverse")
1.40+ (.sgr 27)
1.41+ (print "normal")
1.42+ (.sgr 1 4 7)
1.43+ (print "bold underline reverse")
1.44+ (.sgr 0)
1.45+ (print "normal")
1.46+ (force-output))
1.47+
1.48+(defun ansi-t03 ()
1.49+ "Display the 256 color palette."
1.50+ (clear)
1.51+ (loop for i from 0 to 255 do
1.52+ (.sgr 48 5 i)
1.53+ (princ #\space))
1.54+ (terpri)
1.55+ (.sgr 0)
1.56+ (loop for i from 0 to 255 do
1.57+ (.sgr 38 5 i)
1.58+ (princ "X"))
1.59+ (.sgr 0)
1.60+ (force-output)
1.61+ (sleep 3)
1.62+ (.ris)
1.63+ (force-output))
1.64+
1.65+(defun ansi-t04 ()
1.66+ "Hide and show the cursor."
1.67+ (princ "Cursor visible:")
1.68+ (force-output)
1.69+ (sleep 2)
1.70+ (terpri)
1.71+ (princ "Cursor invisible:")
1.72+ (hide-cursor)
1.73+ (force-output)
1.74+ (sleep 2)
1.75+ (terpri)
1.76+ (princ "Cursor visible:")
1.77+ (show-cursor)
1.78+ (force-output)
1.79+ (sleep 2))
1.80+
1.81+(defun ansi-t05 ()
1.82+ "Switch to and back from the alternate screen buffer."
1.83+ (princ "Normal screen buffer. ")
1.84+ (force-output)
1.85+ (sleep 2)
1.86+ (save-cursor-position)
1.87+ (use-alternate-screen-buffer)
1.88+ (clear)
1.89+ (princ "Alternate screen buffer.")
1.90+ (force-output)
1.91+ (sleep 2)
1.92+ (use-normal-screen-buffer)
1.93+ (restore-cursor-position)
1.94+ (princ "Back to Normal screen buffer.")
1.95+ (force-output)
1.96+ (sleep 1))
1.97+
1.98+(defun ansi-t06 ()
1.99+ "Set individual termios flags to enable raw and disable echo mode.
1.100+
1.101+Enabling raw mode allows read-char to return immediately after a key is pressed.
1.102+
1.103+In the default cooked mode, the entry has to be confirmed by pressing enter."
1.104+ (set-tty-mode t :ignbrk nil
1.105+ :brkint nil
1.106+ :parmrk nil
1.107+ :istrip nil
1.108+ :inlcr nil
1.109+ :igncr nil
1.110+ :icrnl nil
1.111+ :ixon nil
1.112+ :opost nil
1.113+ :echo nil
1.114+ :echonl nil
1.115+ :icanon nil
1.116+ :isig nil
1.117+ :iexten nil
1.118+ :csize nil
1.119+ :parenb nil
1.120+ :vmin 1
1.121+ :vtime 0)
1.122+ (erase)
1.123+ (cursor-position 1 1)
1.124+ (force-output)
1.125+ (let ((a (read-char)))
1.126+ (cursor-position 10 5)
1.127+ (princ a)
1.128+ (force-output))
1.129+
1.130+ (set-tty-mode t :echo t
1.131+ :brkint t
1.132+ :ignpar t
1.133+ :istrip t
1.134+ :icrnl t
1.135+ :ixon t
1.136+ :opost t
1.137+ :isig t
1.138+ :icanon t
1.139+ :veol 0))
1.140+
1.141+(defun ansi-t07 ()
1.142+ "Use combination modes that consist of several individual flags.
1.143+
1.144+Cooked and raw are opposite modes. Enabling cooked disbles raw and vice versa."
1.145+ (set-tty-mode t :cooked nil)
1.146+ (erase)
1.147+ (cursor-position 1 1)
1.148+ (force-output)
1.149+ (let ((a (read-char)))
1.150+ (cursor-position 3 1)
1.151+ (princ a)
1.152+ (force-output))
1.153+ (set-tty-mode t :raw nil))
1.154+
1.155+(defun ansi-t08 ()
1.156+ "Why doesnt calling the stty utility work?"
1.157+ (uiop:run-program "stty raw -echo" :ignore-error-status t)
1.158+ (erase)
1.159+ (cursor-position 1 1)
1.160+ (force-output)
1.161+ (let ((a (read-char)))
1.162+ (cursor-position 2 1)
1.163+ (princ a)
1.164+ (force-output))
1.165+ (uiop:run-program "stty -raw echo" :ignore-error-status t))
1.166+
1.167+(defun ansi-t09 ()
1.168+ "Query terminal size with ANSI escape sequences."
1.169+ ;; Put the terminal into raw mode so we can read the "user input"
1.170+ ;; of the reply char by char
1.171+ ;; Turn off the echo or the sequence will be displayed
1.172+ (set-tty-mode t :cooked nil :echo nil)
1.173+ (save-cursor-position)
1.174+ ;; Go to the bottom right corner of the terminal by attempting
1.175+ ;; to go to some high value of row and column
1.176+ (cursor-position 999 999)
1.177+ (let (chars)
1.178+ ;; The terminal returns an escape sequence to the standard input
1.179+ (device-status-report)
1.180+ (force-output)
1.181+ ;; The reply isnt immediately available, the terminal does need
1.182+ ;; some time to answer
1.183+ (sleep 0.1)
1.184+ ;; The reply has to be read as if the user typed an escape sequence
1.185+ (loop for i = (read-char-no-hang *standard-input* nil)
1.186+ until (null i)
1.187+ do (push i chars))
1.188+ ;; Put the terminal back into its initial cooked state
1.189+ (set-tty-mode t :raw nil :echo t)
1.190+ (restore-cursor-position)
1.191+ ;; Return the read sequence as a list of characters.
1.192+ (nreverse chars)))
1.193+
1.194+(deftest ansi ()
1.195+ ;; (ansi-t01)
1.196+ (ansi-t02)
1.197+ (ansi-t03)
1.198+ (ansi-t04)
1.199+ ;;(ansi-t05)
1.200+)
1.201
1.202 (deftest cli-prompt (:disabled t) ;; FIXME: hijacks io in slime
1.203 "Test CLI prompts"
1.204@@ -21,7 +208,8 @@
1.205 (is (string= "foobar"
1.206 (completing-read "nothing: " tcoll :history thist :default "foobar")))))
1.207
1.208-(defparameter *opts* (cli:make-opts (:name foo :global t :description "bar")
1.209+(defparameter *opts* (cli:make-opts
1.210+ (:name foo :global t :description "bar")
1.211 (:name bar :description "foo")))
1.212
1.213 (defparameter *cmd1* (make-cli :cmd :name "holla" :opts *opts* :description "cmd1 description"))