Parser: hide/show handle `with opacity/visibility/display` strategy, target detection for then-less chaining (add/remove/set/put as boundary). Generator: inline run().toEqual([...]) pattern for eval-only tests. Compiler: hide/show emit correct CSS property per strategy. 373/831 (45%) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
177 lines
5.5 KiB
Plaintext
177 lines
5.5 KiB
Plaintext
;; ==========================================================================
|
||
;; test-text-layout.sx — Tests for Pretext (DOM-free text layout)
|
||
;; ==========================================================================
|
||
;; All tests use fixed widths — no IO, pure arithmetic verification.
|
||
|
||
;; --------------------------------------------------------------------------
|
||
;; Line breaking
|
||
;; --------------------------------------------------------------------------
|
||
|
||
(defsuite
|
||
"line-badness"
|
||
(deftest
|
||
"exact fit has zero badness"
|
||
(assert-equal 0 (line-badness 100 100)))
|
||
(deftest
|
||
"underfull line has positive badness"
|
||
(assert (> (line-badness 50 100) 0)))
|
||
(deftest
|
||
"overfull line has large badness"
|
||
(assert (> (line-badness 110 100) 10000))))
|
||
|
||
(defsuite
|
||
"compute-demerits"
|
||
(deftest
|
||
"zero badness and penalty gives 1"
|
||
(assert-equal 1 (compute-demerits 0 0)))
|
||
(deftest
|
||
"badness contributes quadratically"
|
||
(assert-equal 121 (compute-demerits 10 0)))
|
||
(deftest
|
||
"penalty adds independently"
|
||
(assert-equal 26 (compute-demerits 0 5))))
|
||
|
||
(defsuite
|
||
"sum-widths"
|
||
(deftest
|
||
"single word"
|
||
(assert-equal 10 (sum-widths (list 10 20 30) 5 0 1)))
|
||
(deftest
|
||
"two words with space"
|
||
(assert-equal 35 (sum-widths (list 10 20 30) 5 0 2)))
|
||
(deftest
|
||
"three words with spaces"
|
||
(assert-equal 70 (sum-widths (list 10 20 30) 5 0 3)))
|
||
(deftest
|
||
"subset range"
|
||
(assert-equal 55 (sum-widths (list 10 20 30) 5 1 3))))
|
||
|
||
(defsuite
|
||
"break-lines"
|
||
(deftest "empty input" (assert-equal (list) (break-lines (list) 5 100)))
|
||
(deftest
|
||
"all words fit on one line"
|
||
(let
|
||
((result (break-lines (list 10 20 30) 5 100)))
|
||
(assert-equal 1 (len result))
|
||
(assert-equal (list 0 3) (first result))))
|
||
(deftest
|
||
"forced two-line break"
|
||
(let
|
||
((result (break-lines (list 40 40) 5 50)))
|
||
(assert-equal 2 (len result))
|
||
(assert-equal (list 0 1) (first result))
|
||
(assert-equal (list 1 2) (nth result 1))))
|
||
(deftest
|
||
"three lines from five words"
|
||
(let
|
||
((result (break-lines (list 30 30 30 30 30) 5 70)))
|
||
(assert-equal 3 (len result))))
|
||
(deftest
|
||
"single word per line when words are wide"
|
||
(let
|
||
((result (break-lines (list 80 80 80) 5 90)))
|
||
(assert-equal 3 (len result)))))
|
||
|
||
;; --------------------------------------------------------------------------
|
||
;; Positioning
|
||
;; --------------------------------------------------------------------------
|
||
|
||
(defsuite
|
||
"position-line"
|
||
(deftest
|
||
"single word at origin"
|
||
(let
|
||
((result (position-line (list "hello") (list 50) 5 0 0)))
|
||
(assert-equal 1 (len result))
|
||
(assert-equal 0 (get (first result) :x))
|
||
(assert-equal 0 (get (first result) :y))
|
||
(assert-equal "hello" (get (first result) :word))))
|
||
(deftest
|
||
"two words spaced apart"
|
||
(let
|
||
((result (position-line (list "hi" "there") (list 20 40) 5 0 10)))
|
||
(assert-equal 2 (len result))
|
||
(assert-equal 0 (get (first result) :x))
|
||
(assert-equal 25 (get (nth result 1) :x))
|
||
(assert-equal 10 (get (nth result 1) :y))))
|
||
(deftest
|
||
"custom x offset"
|
||
(let
|
||
((result (position-line (list "word") (list 30) 5 10 0)))
|
||
(assert-equal 10 (get (first result) :x)))))
|
||
|
||
(defsuite
|
||
"position-lines"
|
||
(deftest
|
||
"two lines stacked vertically"
|
||
(let
|
||
((result (position-lines (list "a" "b" "c" "d") (list 10 10 10 10) (list (list 0 2) (list 2 4)) 5 20 0 0)))
|
||
(assert-equal 2 (len result))
|
||
(assert-equal 0 (get (first (first result)) :y))
|
||
(assert-equal 20 (get (first (nth result 1)) :y)))))
|
||
|
||
;; --------------------------------------------------------------------------
|
||
;; Hyphenation
|
||
;; --------------------------------------------------------------------------
|
||
|
||
(defsuite
|
||
"hyphenation-trie"
|
||
(deftest
|
||
"build trie from patterns"
|
||
(let
|
||
((trie (make-hyphenation-trie (list "hy1p" "he2n"))))
|
||
(assert (dict? trie))
|
||
(assert (has-key? trie :children))))
|
||
(deftest
|
||
"trie has expected structure"
|
||
(let
|
||
((trie (make-hyphenation-trie (list "ab1c"))))
|
||
(assert (has-key? (get trie :children) "a")))))
|
||
|
||
(defsuite
|
||
"hyphenate-word"
|
||
(deftest
|
||
"word with no patterns returns single syllable"
|
||
(let
|
||
((trie (make-hyphenation-trie (list))))
|
||
(assert-equal (list "xyz") (hyphenate-word trie "xyz"))))
|
||
(deftest
|
||
"simple hyphenation"
|
||
(let
|
||
((trie (make-hyphenation-trie (list "hy1phen"))))
|
||
(let
|
||
((syllables (hyphenate-word trie "hyphen")))
|
||
(assert (>= (len syllables) 1))))))
|
||
|
||
;; --------------------------------------------------------------------------
|
||
;; Integration: break + position
|
||
;; --------------------------------------------------------------------------
|
||
|
||
(defsuite
|
||
"layout-integration"
|
||
(deftest
|
||
"break and position round-trip"
|
||
(let
|
||
((widths (list 30 30 30 30))
|
||
(words (list "one" "two" "three" "four"))
|
||
(space-width 5)
|
||
(max-width 70)
|
||
(line-height 20))
|
||
(let
|
||
((ranges (break-lines widths space-width max-width)))
|
||
(let
|
||
((positioned (position-lines words widths ranges space-width line-height 0 0)))
|
||
(assert (> (len positioned) 0))
|
||
(assert-equal 0 (get (first (first positioned)) :x))
|
||
(assert-equal 0 (get (first (first positioned)) :y))))))
|
||
(deftest
|
||
"total height is lines × line-height"
|
||
(let
|
||
((widths (list 80 80 80))
|
||
(space-width 5)
|
||
(max-width 90)
|
||
(line-height 20))
|
||
(let
|
||
((ranges (break-lines widths space-width max-width)))
|
||
(assert-equal 3 (len ranges)))))) |