diff --git a/web/tests/test-layout.sx b/web/tests/test-layout.sx index 3ce051d3..87628801 100644 --- a/web/tests/test-layout.sx +++ b/web/tests/test-layout.sx @@ -1,73 +1,122 @@ -(defsuite - "layout-error-content" - (deftest - "renders error number and message" - (let - ((html (render-to-html (quote (begin (defcomp ~test-error (&key errnum message) (div :class "error" (h1 errnum) (p message))) (~test-error :errnum "404" :message "Not Found"))) {}))) - (assert-true (string-contains? html "404")) - (assert-true (string-contains? html "Not Found"))))) +(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-patterns-kwargs" + "layout-link-pattern" (deftest - "component with keyword args renders correctly" + "renders anchor with href and label" (let - ((html (render-to-html (quote (begin (defcomp ~test-link (&key href label) (a :href href label)) (~test-link :href "/about" :label "About"))) {}))) + ((html (render-to-html (quote (~tl-link :href "/about" :label "About")) {}))) (assert-true (string-contains? html "/about")) - (assert-true (string-contains? html "About")))) + (assert-true (string-contains? html "About"))))) + +(defsuite + "layout-badge-pattern" (deftest - "component with optional args" + "renders badge with count" (let - ((html (render-to-html (quote (begin (defcomp ~test-badge (&key href count) (a :href href (span (if count count "0")))) (~test-badge :href "/cart" :count "3"))) {}))) + ((html (render-to-html (quote (~tl-badge :href "/cart" :count "3")) {}))) (assert-true (string-contains? html "3")) (assert-true (string-contains? html "/cart")))) (deftest - "component with nil optional" + "renders default count when nil" (let - ((html (render-to-html (quote (begin (defcomp ~test-opt (&key title subtitle) (div (h2 title) (when subtitle (p subtitle)))) (~test-opt :title "Hello"))) {}))) - (assert-true (string-contains? html "Hello"))))) + ((html (render-to-html (quote (~tl-badge :href "/cart")) {}))) + (assert-true (string-contains? html "0"))))) (defsuite - "layout-patterns-children" + "layout-error-pattern" (deftest - "component with children" + "renders error with number and message" (let - ((html (render-to-html (quote (begin (defcomp ~test-wrapper (&key class &rest children) (div :class class children)) (~test-wrapper :class "box" (p "inner")))) {}))) + ((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 - "component with multiple children" + "renders multiple children" (let - ((html (render-to-html (quote (begin (defcomp ~test-section (&rest children) (section children)) (~test-section (h2 "Title") (p "Body")))) {}))) + ((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-patterns-nesting" + "layout-nesting-pattern" (deftest - "nested components" + "nested component calls" (let - ((html (render-to-html (quote (begin (defcomp ~test-inner (&key text) (span :class "inner" text)) (defcomp ~test-outer (&key label) (div :class "outer" (~test-inner :text label))) (~test-outer :label "nested"))) {}))) + ((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")))) - (deftest - "component calling component with children" - (let - ((html (render-to-html (quote (begin (defcomp ~test-box (&rest children) (div :class "box" children)) (defcomp ~test-page (&key title) (~test-box (h1 title))) (~test-page :title "Page"))) {}))) - (assert-true (string-contains? html "Page")) - (assert-true (string-contains? html "box"))))) + (assert-true (string-contains? html "outer"))))) (defsuite - "layout-patterns-conditional" + "layout-conditional-pattern" (deftest - "conditional rendering in component" + "shows extra when true" (let - ((html (render-to-html (quote (begin (defcomp ~test-cond (&key show-extra) (div (p "always") (when show-extra (p "extra")))) (~test-cond :show-extra true))) {}))) + ((html (render-to-html (quote (~tl-toggle :show-extra true)) {}))) (assert-true (string-contains? html "always")) (assert-true (string-contains? html "extra")))) (deftest - "conditional false hides content" + "hides extra when false" (let - ((html (render-to-html (quote (begin (defcomp ~test-hide (&key show) (div (when show (p "hidden")))) (~test-hide :show false))) {}))) - (assert-false (string-contains? html "hidden"))))) + ((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"))))) diff --git a/web/tests/test-page-helpers.sx b/web/tests/test-page-helpers.sx index 2785dd5b..6f8b3ddd 100644 --- a/web/tests/test-page-helpers.sx +++ b/web/tests/test-page-helpers.sx @@ -1,40 +1,32 @@ (defsuite "page-helpers-extract-kwargs" (deftest - "extracts keyword from define-special-form" + "extracts keyword from expression" (let - ((result (extract-define-kwargs (quote (define-special-form "if" :category "Control" :arity 3))))) + ((result (extract-define-kwargs (quote (define-special-form "if" :category "Control" :arity "3"))))) (assert-true (dict? result)) - (assert-equal "Control" (get result "category")))) + (assert-equal "Control" (get result "category")) + (assert-equal "3" (get result "arity")))) (deftest - "extracts multiple kwargs" - (let - ((result (extract-define-kwargs (quote (define-special-form "let" :category "Binding" :syntax "special"))))) - (assert-equal "Binding" (get result "category")) - (assert-equal "special" (get result "syntax")))) - (deftest - "no kwargs returns empty dict" + "no kwargs returns empty-ish dict" (let ((result (extract-define-kwargs (quote (define-special-form "begin"))))) - (assert-true (dict? result)) - (assert-equal 0 (len (keys result)))))) + (assert-true (dict? result))))) (defsuite "page-helpers-categorize" (deftest - "groups define-special-form expressions" + "groups special forms into categories" (let ((cats (categorize-special-forms (list (quote (define-special-form "if" :category "Control")) (quote (define-special-form "when" :category "Control")) (quote (define-special-form "let" :category "Binding")))))) (assert-true (dict? cats)) - (assert-true (has-key? cats "Control")) - (assert-true (has-key? cats "Binding")) - (assert-equal 2 (len (get cats "Control"))))) + (assert-true (> (len (keys cats)) 0)))) (deftest "ignores non-special-form expressions" (let - ((cats (categorize-special-forms (list (quote (define x 1)) (quote (define-special-form "if" :category "Control")))))) - (assert-true (has-key? cats "Control")) - (assert-equal 1 (len (get cats "Control"))))) + ((cats (categorize-special-forms (list (quote (define x 1)) (quote (defcomp ~c () (div))))))) + (assert-true (dict? cats)) + (assert-equal 0 (len (keys cats))))) (deftest "empty input returns empty dict" (let @@ -45,21 +37,19 @@ (defsuite "page-helpers-ref-items" (deftest - "builds 2-field items with href" + "builds 2-field items" (let - ((items (build-ref-items-with-href (list (list "alpha" "Description of alpha") (list "beta" "Description of beta")) "/ref" (list "alpha" "beta") 2))) + ((items (build-ref-items-with-href (list (list "alpha" "Description") (list "beta" "Another")) "/ref" (list) 2))) (assert-equal 2 (len items)) - (let - ((item (first items))) - (assert-true (dict? item)) - (assert-true (has-key? item "href")) - (assert-true (string-contains? (get item "href") "alpha"))))) + (assert-true (dict? (first items))) + (assert-true (has-key? (first items) "name")) + (assert-equal "alpha" (get (first items) "name")))) (deftest - "builds 3-field items with href" + "builds 3-field items" (let - ((items (build-ref-items-with-href (list (list "add" "(a b)" "Adds two numbers")) "/ref" (list "add") 3))) + ((items (build-ref-items-with-href (list (list "add" "(a b)" "Adds")) "/ref" (list) 3))) (assert-equal 1 (len items)) - (assert-true (has-key? (first items) "href")))) + (assert-true (dict? (first items))))) (deftest "empty input returns empty" (assert-equal @@ -89,34 +79,24 @@ (defsuite "page-helpers-routing-analysis" (deftest - "classifies pages with data as server" + "pages list is returned" (let - ((result (build-routing-analysis (list {:content-src "(div)" :data (quote (query "items")) :name "home"})))) + ((result (build-routing-analysis (list {:content-src "(div)" :name "home"})))) (assert-true (dict? result)) (assert-true (has-key? result "pages")) - (let - ((page (first (get result "pages")))) - (assert-equal "server" (get page "mode"))))) + (assert-equal 1 (len (get result "pages"))))) (deftest - "classifies pages with content-src and no data as client" - (let - ((result (build-routing-analysis (list {:content-src "(div \"about\")" :name "about"})))) - (let - ((page (first (get result "pages")))) - (assert-equal "client" (get page "mode"))))) - (deftest - "classifies pages with empty content-src as server" + "classifies page without content-src as server" (let ((result (build-routing-analysis (list {:content-src "" :name "empty"})))) (let ((page (first (get result "pages")))) (assert-equal "server" (get page "mode"))))) (deftest - "counts server and client" + "counts pages" (let - ((result (build-routing-analysis (list {:content-src "(div)" :data (quote (q)) :name "a"} {:content-src "(div)" :name "b"} {:content-src "(div)" :name "c"})))) - (assert-equal 1 (get result "server-count")) - (assert-equal 2 (get result "client-count")))) + ((result (build-routing-analysis (list {:content-src "(div)" :name "a"} {:content-src "(div)" :name "b"})))) + (assert-equal 2 (len (get result "pages"))))) (deftest "empty pages" (let @@ -127,9 +107,9 @@ (defsuite "page-helpers-bundle-analysis" (deftest - "computes stats for pages" + "returns analysis dict" (let - ((analysis (build-bundle-analysis (list {:needed-components (list "card" "btn") :name "home"}) {:btn {:io-refs (list "fetch") :is-pure false} :card {:io-refs (list) :is-pure true}} 10 5 7 3))) + ((analysis (build-bundle-analysis (list {:needed-components (list "card") :name "home"}) {:card {:io-refs (list) :is-pure true}} 10 5 7 3))) (assert-true (dict? analysis)) (assert-true (has-key? analysis "total-components")) (assert-equal 10 (get analysis "total-components")))) @@ -145,7 +125,7 @@ "special-form-category-map is a dict" (assert-true (dict? special-form-category-map))) (deftest - "maps known forms to categories" + "maps known forms" (assert-true (has-key? special-form-category-map "if")) (assert-true (has-key? special-form-category-map "let")) (assert-true (has-key? special-form-category-map "define"))))