Files
clojure-tui/test/tui/render_test.clj
2026-01-21 10:30:07 -05:00

157 lines
5.7 KiB
Clojure

(ns tui.render-test
"Unit tests for hiccup rendering."
(:require [clojure.test :refer [deftest testing is]]
[clojure.string :as str]
[tui.render :as render]
[tui.ansi :as ansi]))
;; === Text Rendering Tests ===
(deftest render-plain-text-test
(testing "renders plain strings"
(is (= "hello" (render/render "hello")))
(is (= "world" (render/render "world"))))
(testing "renders numbers as strings"
(is (= "42" (render/render 42)))
(is (= "3.14" (render/render 3.14))))
(testing "renders nil as empty string"
(is (= "" (render/render nil)))))
(deftest render-text-element-test
(testing "renders :text element with string child"
(is (= "hello" (render/render [:text "hello"]))))
(testing "renders :text element with multiple children"
(is (= "hello world" (render/render [:text "hello" " " "world"]))))
(testing "renders nested text"
(is (= "42" (render/render [:text 42])))))
(deftest render-styled-text-test
(testing "renders bold text"
(let [result (render/render [:text {:bold true} "bold"])]
(is (str/includes? result "bold"))
(is (str/includes? result "\u001b[")) ; Contains ANSI escape
(is (str/includes? result "1m")))) ; Bold code
(testing "renders colored text"
(let [result (render/render [:text {:fg :red} "red"])]
(is (str/includes? result "red"))
(is (str/includes? result "31m")))) ; Red foreground code
(testing "renders multiple styles"
(let [result (render/render [:text {:bold true :fg :green} "styled"])]
(is (str/includes? result "styled"))
(is (str/includes? result "1")) ; Bold
(is (str/includes? result "32"))))) ; Green
;; === Layout Tests ===
(deftest render-row-test
(testing "renders row with children horizontally"
(is (= "ab" (render/render [:row "a" "b"])))
(is (= "abc" (render/render [:row "a" "b" "c"]))))
(testing "renders row with gap"
(is (= "a b" (render/render [:row {:gap 1} "a" "b"])))
(is (= "a b" (render/render [:row {:gap 2} "a" "b"]))))
(testing "renders nested elements in row"
(is (= "hello world" (render/render [:row [:text "hello"] " " [:text "world"]])))))
(deftest render-col-test
(testing "renders col with children vertically"
(is (= "a\nb" (render/render [:col "a" "b"])))
(is (= "a\nb\nc" (render/render [:col "a" "b" "c"]))))
(testing "renders col with gap"
(is (= "a\n\nb" (render/render [:col {:gap 1} "a" "b"])))
(is (= "a\n\n\nb" (render/render [:col {:gap 2} "a" "b"]))))
(testing "renders nested elements in col"
(is (= "line1\nline2" (render/render [:col [:text "line1"] [:text "line2"]])))))
(deftest render-nested-layout-test
(testing "renders row inside col"
(is (= "a b\nc d" (render/render [:col
[:row "a" " " "b"]
[:row "c" " " "d"]]))))
(testing "renders col inside row"
(is (= "a\nb c\nd" (render/render [:row
[:col "a" "b"]
" "
[:col "c" "d"]])))))
;; === Box Tests ===
(deftest render-box-test
(testing "renders box with content"
(let [result (render/render [:box "hello"])]
(is (str/includes? result "hello"))
(is (str/includes? result "─")) ; Horizontal border
(is (str/includes? result "│")))) ; Vertical border
(testing "renders box with title"
(let [result (render/render [:box {:title "Title"} "content"])]
(is (str/includes? result "Title"))
(is (str/includes? result "content"))))
(testing "renders box with different border styles"
(let [rounded (render/render [:box {:border :rounded} "x"])
single (render/render [:box {:border :single} "x"])
double (render/render [:box {:border :double} "x"])
ascii (render/render [:box {:border :ascii} "x"])]
(is (str/includes? rounded "╭"))
(is (str/includes? single "┌"))
(is (str/includes? double "╔"))
(is (str/includes? ascii "+")))))
(deftest render-box-padding-test
(testing "renders box with numeric padding"
(let [result (render/render [:box {:padding 1} "x"])
lines (str/split result #"\n")]
;; Should have empty lines for vertical padding
(is (> (count lines) 3))))
(testing "renders box with vector padding"
(let [result (render/render [:box {:padding [0 2]} "x"])]
;; Should have horizontal padding (spaces around content)
(is (str/includes? result " x ")))))
;; === Space Tests ===
(deftest render-space-test
(testing "renders space with default size"
(is (= " " (render/render [:space]))))
(testing "renders space with custom width"
(is (= " " (render/render [:space {:width 3}]))))
(testing "renders space with custom height"
(is (= " \n " (render/render [:space {:height 2}]))))
(testing "renders space with width and height"
(is (= " \n " (render/render [:space {:width 2 :height 2}])))))
;; === Convenience Function Tests ===
(deftest convenience-functions-test
(testing "text function creates text element"
(is (= [:text {} "hello"] (render/text "hello")))
(is (= [:text {:bold true} "bold"] (render/text {:bold true} "bold"))))
(testing "row function creates row element"
(is (= [:row {} "a" "b"] (render/row "a" "b")))
(is (= [:row {:gap 1} "a" "b"] (render/row {:gap 1} "a" "b"))))
(testing "col function creates col element"
(is (= [:col {} "a" "b"] (render/col "a" "b")))
(is (= [:col {:gap 1} "a" "b"] (render/col {:gap 1} "a" "b"))))
(testing "box function creates box element"
(is (= [:box {} "content"] (render/box "content")))
(is (= [:box {:border :single} "x"] (render/box {:border :single} "x")))))