(defcomp ~tl-link (&key href label) (a :href href label)) (defcomp ~tl-badge (&key href count) (a :href href (span (if count count "0")))) (defcomp ~tl-error (&key errnum message image) (div :class "error" (h1 errnum) (p message) (when image (img :src image)))) (defcomp ~tl-wrapper (&key class &rest children) (div :class class children)) (defcomp ~tl-inner (&key text) (span :class "inner" text)) (defcomp ~tl-outer (&key label) (div :class "outer" (~tl-inner :text label))) (defcomp ~tl-toggle (&key show-extra) (div (p "always") (when show-extra (p "extra")))) (defcomp ~tl-clear (&key id) (div :id id)) (defsuite "layout-link-pattern" (deftest "renders anchor with href and label" (let ((html (render-to-html (quote (~tl-link :href "/about" :label "About")) {}))) (assert-true (string-contains? html "/about")) (assert-true (string-contains? html "About"))))) (defsuite "layout-badge-pattern" (deftest "renders badge with count" (let ((html (render-to-html (quote (~tl-badge :href "/cart" :count "3")) {}))) (assert-true (string-contains? html "3")) (assert-true (string-contains? html "/cart")))) (deftest "renders default count when nil" (let ((html (render-to-html (quote (~tl-badge :href "/cart")) {}))) (assert-true (string-contains? html "0"))))) (defsuite "layout-error-pattern" (deftest "renders error with number and message" (let ((html (render-to-html (quote (~tl-error :errnum "404" :message "Not Found")) {}))) (assert-true (string-contains? html "404")) (assert-true (string-contains? html "Not Found")))) (deftest "renders with image when provided" (let ((html (render-to-html (quote (~tl-error :errnum "500" :message "Error" :image "/err.png")) {}))) (assert-true (string-contains? html "500")) (assert-true (string-contains? html "/err.png")))) (deftest "omits image when nil" (let ((html (render-to-html (quote (~tl-error :errnum "404" :message "Missing")) {}))) (assert-false (string-contains? html "img"))))) (defsuite "layout-children-pattern" (deftest "renders children inside wrapper" (let ((html (render-to-html (quote (~tl-wrapper :class "box" (p "inner"))) {}))) (assert-true (string-contains? html "inner")) (assert-true (string-contains? html "box")))) (deftest "renders multiple children" (let ((html (render-to-html (quote (~tl-wrapper :class "section" (h2 "Title") (p "Body"))) {}))) (assert-true (string-contains? html "Title")) (assert-true (string-contains? html "Body"))))) (defsuite "layout-nesting-pattern" (deftest "nested component calls" (let ((html (render-to-html (quote (~tl-outer :label "nested")) {}))) (assert-true (string-contains? html "nested")) (assert-true (string-contains? html "inner")) (assert-true (string-contains? html "outer"))))) (defsuite "layout-conditional-pattern" (deftest "shows extra when true" (let ((html (render-to-html (quote (~tl-toggle :show-extra true)) {}))) (assert-true (string-contains? html "always")) (assert-true (string-contains? html "extra")))) (deftest "hides extra when false" (let ((html (render-to-html (quote (~tl-toggle :show-extra false)) {}))) (assert-true (string-contains? html "always")) (assert-false (string-contains? html "extra"))))) (defsuite "layout-clear-pattern" (deftest "renders div with id" (let ((html (render-to-html (quote (~tl-clear :id "sidebar")) {}))) (assert-true (string-contains? html "sidebar")))))