Implements the modern-backend with truecolor SGR, Unicode box-drawing (rounded/double/single), DECICM synchronized updates, OSC 8 hyperlinks, cursor style control, and hex color parsing. RED: 32 checks, 5 fail (class forward-ref + test bug) GREEN: 32/32 checks passing (100%) - backend/modern.lisp — escape generators + modern-backend class - backend/modern-tests.lisp — 16 test cases, 32 assertions - backend/package.lisp — updated exports - org/modern-backend.org — literate source
125 lines
5.1 KiB
Common Lisp
125 lines
5.1 KiB
Common Lisp
(defpackage :cl-tui-modern-backend-test
|
|
(:use :cl :fiveam :cl-tui.backend)
|
|
(:export #:run-tests))
|
|
(in-package :cl-tui-modern-backend-test)
|
|
|
|
(def-suite modern-backend-suite :description "Modern backend tests")
|
|
(in-suite modern-backend-suite)
|
|
|
|
(defun run-tests ()
|
|
(let ((result (run 'modern-backend-suite)))
|
|
(fiveam:explain! result)
|
|
(uiop:quit 0)))
|
|
|
|
;; ── Constructor ────────────────────────────────────────────────
|
|
|
|
(test make-modern-backend-creates
|
|
"make-modern-backend returns a modern-backend instance"
|
|
(let ((b (make-modern-backend)))
|
|
(is (typep b 'cl-tui.backend::modern-backend))))
|
|
|
|
;; ── Escape Generation ──────────────────────────────────────────
|
|
|
|
(test sgr-truecolor-foreground
|
|
"SGR truecolor foreground escape is correct"
|
|
(is (equal (cl-tui.backend::sgr-fg "#FFD700")
|
|
(format nil "~C[38;2;255;215;0m" #\Esc))))
|
|
|
|
(test sgr-truecolor-background
|
|
"SGR truecolor background escape is correct"
|
|
(is (equal (cl-tui.backend::sgr-bg "#1a1b26")
|
|
(format nil "~C[48;2;26;27;38m" #\Esc))))
|
|
|
|
(test sgr-named-colors
|
|
"SGR named colors resolve to 8-color codes"
|
|
(is (equal (cl-tui.backend::sgr-fg :red)
|
|
(format nil "~C[31m" #\Esc)))
|
|
(is (equal (cl-tui.backend::sgr-bg :blue)
|
|
(format nil "~C[44m" #\Esc))))
|
|
|
|
(test sgr-bold-italic
|
|
"SGR attribute escapes are correct"
|
|
(is (equal (cl-tui.backend::sgr-attr :bold) (format nil "~C[1m" #\Esc)))
|
|
(is (equal (cl-tui.backend::sgr-attr :italic) (format nil "~C[3m" #\Esc)))
|
|
(is (equal (cl-tui.backend::sgr-attr :underline) (format nil "~C[4m" #\Esc)))
|
|
(is (equal (cl-tui.backend::sgr-attr :reset) (format nil "~C[0m" #\Esc))))
|
|
|
|
;; ── Cursor ─────────────────────────────────────────────────────
|
|
|
|
(test cursor-move-escape
|
|
"cursor-move generates correct CSI escape"
|
|
(let ((b (make-modern-backend)))
|
|
(is (equal (cl-tui.backend::cursor-move-escape 5 10)
|
|
(format nil "~C[11;6H" #\Esc)))))
|
|
|
|
(test cursor-style-block
|
|
"cursor-style :block generate correct escape"
|
|
(let ((b (make-modern-backend)))
|
|
(is (equal (cl-tui.backend::cursor-style-escape :block nil)
|
|
(format nil "~C[2 q" #\Esc)))))
|
|
|
|
(test cursor-style-bar
|
|
"cursor-style :bar generate correct escape"
|
|
(let ((b (make-modern-backend)))
|
|
(is (equal (cl-tui.backend::cursor-style-escape :bar nil)
|
|
(format nil "~C[6 q" #\Esc)))))
|
|
|
|
(test cursor-style-underline-blink
|
|
"cursor-style :underline with blink"
|
|
(let ((b (make-modern-backend)))
|
|
(is (equal (cl-tui.backend::cursor-style-escape :underline t)
|
|
(format nil "~C[5 q" #\Esc)))))
|
|
|
|
;; ── Synchronization ────────────────────────────────────────────
|
|
|
|
(test decicm-escapes
|
|
"DECICM synchronized update escapes"
|
|
(is (equal (cl-tui.backend::decicm-begin) (format nil "~C[?2026h" #\Esc)))
|
|
(is (equal (cl-tui.backend::decicm-end) (format nil "~C[?2026l" #\Esc))))
|
|
|
|
;; ── OSC 8 Hyperlinks ──────────────────────────────────────────
|
|
|
|
(test osc8-escape
|
|
"OSC 8 hyperlink escape wraps text"
|
|
(is (equal (cl-tui.backend::osc8-link "http://example.com" "click here")
|
|
(format nil "~C]8;;http://example.com~C\\click here~C]8;;~C\\"
|
|
#\Esc #\Esc #\Esc #\Esc))))
|
|
|
|
;; ── Hex Parsing ────────────────────────────────────────────────
|
|
|
|
(test hex-color-parsing
|
|
"hex-to-rgb parses valid hex colors"
|
|
(multiple-value-bind (r g b) (cl-tui.backend::hex-to-rgb "#FFD700")
|
|
(is (= r 255))
|
|
(is (= g 215))
|
|
(is (= b 0))))
|
|
|
|
(test hex-color-black
|
|
"hex-to-rgb parses black"
|
|
(multiple-value-bind (r g b) (cl-tui.backend::hex-to-rgb "#000000")
|
|
(is (= r 0))
|
|
(is (= g 0))
|
|
(is (= b 0))))
|
|
|
|
(test hex-color-short-form
|
|
"hex-to-rgb parses 3-digit hex"
|
|
(multiple-value-bind (r g b) (cl-tui.backend::hex-to-rgb "#F00")
|
|
(is (= r 255))
|
|
(is (= g 0))
|
|
(is (= b 0))))
|
|
|
|
;; ── Border Characters ──────────────────────────────────────────
|
|
|
|
(test border-char-rounded
|
|
"modern-border-char returns Unicode box-drawing for rounded style"
|
|
(is (equal (cl-tui.backend::border-char :rounded :top-left) "╭"))
|
|
(is (equal (cl-tui.backend::border-char :rounded :horizontal) "─"))
|
|
(is (equal (cl-tui.backend::border-char :rounded :vertical) "│"))
|
|
(is (equal (cl-tui.backend::border-char :rounded :bottom-right) "╯")))
|
|
|
|
(test border-char-double
|
|
"modern-border-char returns double-line chars"
|
|
(is (equal (cl-tui.backend::border-char :double :top-left) "╔"))
|
|
(is (equal (cl-tui.backend::border-char :double :horizontal) "═"))
|
|
(is (equal (cl-tui.backend::border-char :double :vertical) "║")))
|