literate: add org sources for orphan test files, update README

- Create org/integration-tests.org (15 blocks, per-test prose)
- Add Markdown tests section to org/markdown-renderer.org (11 test blocks)
- Delete deprecated src/components/input-tests.lisp stub
- Update README.org: tree diagram, literate programming section,
  development commands, remove stale test counts

All 13 test suites pass at 100%. Zero .lisp files without org origin.
This commit is contained in:
Hermes Agent
2026-05-12 19:01:22 +00:00
parent 29f99a576d
commit a9670a5cd7
6 changed files with 923 additions and 77 deletions

View File

@@ -2,6 +2,8 @@
;;;
;;; Composes all major components through the rendering pipeline onto a
;;; framebuffer backend and verifies cell-level output.
;;;
;;; This file is tangled from org/integration-tests.org — do not edit directly.
(defpackage :cl-tty-integration-test
(:use :cl :fiveam
@@ -16,13 +18,12 @@
(in-suite integration-suite)
;; ─── Helper: extract cell text from a region ──────────────────────
(defun fb-string (fb x y &optional (len 1))
"Read a string of LEN characters from framebuffer FB starting at (X,Y)."
(let* ((cells (fb-framebuffer fb))
(w (framebuffer-width cells))
(h (framebuffer-height cells)))
(declare (ignore h))
(with-output-to-string (s)
(loop for i from 0 below len
for cx = (+ x i)
@@ -35,16 +36,15 @@
(w (framebuffer-width cells))
(h (framebuffer-height cells))
(max-row (min (or end-row h) h)))
(declare (ignore w))
(loop for y from start-row below max-row
collect (fb-string fb 0 y w))))
collect (fb-string fb 0 y (framebuffer-width cells)))))
(defun fb-contains (fb text)
"Return T if framebuffer FB contains TEXT anywhere."
(let ((all-text (format nil "~{~a~^~%~}" (fb-lines fb))))
(search text all-text :test #'char-equal)))
;; ─── Test: Box with title renders correctly ───────────────────────
(test box-title-renders-on-fb
"A Box with a title draws border and title text on framebuffer."
(let* ((fb (make-framebuffer-backend :width 40 :height 10))
@@ -58,8 +58,6 @@
;; Check the title at row 0, col 2
(is (equal "My Box" (fb-string fb 2 1 6)) "title at correct position")))
;; ─── Test: Text component with word-wrap ──────────────────────────
(test text-component-on-fb
"Text component renders word-wrapped content on framebuffer."
(let* ((fb (make-framebuffer-backend :width 20 :height 6))
@@ -71,8 +69,6 @@
(is-true (fb-contains fb "brave") "second word appears")
(is-true (fb-contains fb "world") "third word wraps")))
;; ─── Test: TextInput with value ───────────────────────────────────
(test textinput-value-on-fb
"TextInput renders its value and cursor on framebuffer."
(let* ((fb (make-framebuffer-backend :width 40 :height 3))
@@ -88,8 +84,6 @@
(cursor-char (cell-char (aref cells 0 11))))
(is (eql #\█ cursor-char) "cursor block is drawn at position 11"))))
;; ─── Test: TextInput empty shows placeholder ──────────────────────
(test textinput-placeholder-on-fb
"TextInput with empty value shows placeholder text."
(let* ((fb (make-framebuffer-backend :width 40 :height 3))
@@ -100,8 +94,6 @@
(render ti fb)
(is (equal "Type here..." (fb-string fb 0 0 12)) "placeholder appears at row 0")))
;; ─── Test: ScrollBox with children ────────────────────────────────
(test scrollbox-children-on-fb
"ScrollBox renders visible children offset by scroll position."
(let* ((fb (make-framebuffer-backend :width 40 :height 10))
@@ -130,8 +122,6 @@
(is-false (fb-contains fb "Line 1") "Line 1 scrolled out")
(is-false (fb-contains fb "Line 2") "Line 2 scrolled out"))))
;; ─── Test: Select renders options ─────────────────────────────────
(test select-options-on-fb
"Select renders option titles on framebuffer."
(let* ((fb (make-framebuffer-backend :width 40 :height 10))
@@ -147,8 +137,6 @@
(is-true (fb-contains fb "Green") "second option appears")
(is-true (fb-contains fb "Blue") "third option appears")))
;; ─── Test: Dialog renders with backdrop ───────────────────────────
(test dialog-appears-on-fb
"Dialog renders a dimmed backdrop and dialog panel with title."
(let* ((fb (make-framebuffer-backend :width 80 :height 24))
@@ -163,8 +151,6 @@
;; Clean up
(pop-dialog)))
;; ─── Test: Dialog push/pop with render ────────────────────────────
(test dialog-push-pop-render
"Dialog push/pop cycle works with rendering."
(let* ((fb (make-framebuffer-backend :width 80 :height 24))
@@ -180,8 +166,6 @@
(is-true (fb-contains fb "Dialog One") "second dialog renders after pop")
(pop-dialog)))
;; ─── Test: Toast renders ──────────────────────────────────────────
(test toast-appears-on-fb
"Toast notification renders with colored background."
(let* ((fb (make-framebuffer-backend :width 80 :height 24)))
@@ -190,8 +174,6 @@
(is-true (fb-contains fb "Hello from toast!") "toast message appears")
(dismiss-toast (first *toasts*))))
;; ─── Test: render-screen pipeline ─────────────────────────────────
(test render-screen-pipeline
"render-screen processes a component tree through the full pipeline."
(let* ((fb (make-framebuffer-backend :width 40 :height 12))
@@ -202,8 +184,6 @@
;; Border characters (ASCII on framebuffer)
(is-true (fb-contains fb "+") "border renders")))
;; ─── Test: Full composition via framebuffer ───────────────────────
(test full-composition-via-fb
"All components compose correctly on a single framebuffer."
(let* ((fb (make-framebuffer-backend :width 60 :height 24)))