(ns dompa.nodes-test #?(:clj (:require [clojure.test :refer [deftest is testing]] [clojure.zip :as zip] [dompa.html :as html] [dompa.nodes :as nodes :refer [$ defhtml]])) #?(:cljs (:require [cljs.test :refer-macros [deftest testing is]] [clojure.zip :as zip] [dompa.nodes :as nodes :refer [$] :refer-macros [defhtml]] [dompa.html :as html]))) (defhtml hello [who] ($ :div ($ "hello " who))) (deftest defhtml-test (is (= "
hello world
" (hello "world")))) (defhtml list-items [items] ($ :ul (->> items (map (fn [item] ($ :li item))) (into [])))) (deftest list-items-test (is (= "" (list-items ["one" "two" "three"])))) (defhtml empty-list-items [items] ($ :ul (map (fn [item] ($ :li item)) items))) (deftest empty-list-items-test (testing "map over empty vector should not produce LazySeq string" (is (= "" (empty-list-items [])))) (testing "map over non-empty vector should work" (is (= "" (empty-list-items ["one" "two"]))))) (defhtml greeting [who] ($ :span who)) (defhtml page [who] ($ :div (greeting who))) (defhtml badge [text] ($ :span {:class "badge"} text)) (defhtml card [title] ($ :div {:class "card"} (badge title))) (defhtml list-item [text] ($ :li text)) (defhtml my-list [items] ($ :ul (->> items (map list-item) (into [])))) (defhtml header [title] ($ :h1 title)) (defhtml nav [items] ($ :nav ($ :ul (->> items (map list-item) (into []))))) (defhtml layout [title nav-items body] ($ :div (header title) (nav nav-items) ($ :main body))) (deftest nested-defhtml-test (testing "simple nesting of defhtml" (is (= "
world
" (page "world")))) (testing "nested defhtml with attributes" (is (= "
Hello
" (card "Hello")))) (testing "nested defhtml via map/collection" (is (= "" (my-list ["a" "b" "c"])))) (testing "deeply nested defhtml (three levels)" (is (= "

Title

content
" (layout "Title" ["a" "b"] "content")))) (testing "mixing defhtml and $ in the same parent" (is (= "
hi

bye

" (nodes/->html [($ :div (greeting "hi") ($ :p "bye"))]))))) (deftest $-test (testing "a simple node" (is (= {:node/name :div :node/children [{:node/name :dompa/text :node/value "hello world"}]} ($ :div "hello world")))) (testing "a fragment node" (is (= {:node/name :<> :node/children [{:node/name :span :node/children [{:node/name :dompa/text :node/value "hello"}]} {:node/name :span :node/children [{:node/name :dompa/text :node/value "world"}]}]} ($ :<> ($ :span ($ "hello")) ($ :span ($ "world")))))) (testing "a nil node" (is (= nil ($ nil)))) (testing "a string node" (is (= {:node/name :dompa/text :node/value "hello world"} ($ "hello world")))) (testing "a node of multiple sub-nodes" (is (= {:node/name :<> :node/children [{:node/name :dompa/text :node/value "hello"} {:node/name :dompa/text :node/value "12345"} {:node/name :dompa/text :node/value "123.3"} {:node/name :dompa/text :node/value "world"}]} ($ "hello" 12345 nil 123.3 "world"))) (is (= {:node/name :<> :node/children [{:node/name :dompa/text :node/value "hello"} {:node/name :dompa/text :node/value "12345"} {:node/name :<> :node/children [{:node/name :dompa/text :node/value "w"} {:node/name :dompa/text :node/value "o"} {:node/name :dompa/text :node/value "r"} {:node/name :dompa/text :node/value "l"} {:node/name :dompa/text :node/value "d"}]}]} ($ "hello" 12345 (map #($ %) ["w" "o" "r" "l" "d"])))) (is (= {:node/name :<> :node/children [{:node/name :dompa/text :node/value "hello"} {:node/name :<> :node/children [{:node/name :dompa/text :node/value "w"} {:node/name :<> :node/children [{:node/name :dompa/text :node/value "o"} {:node/name :dompa/text :node/value "r"} {:node/name :<> :node/children [{:node/name :dompa/text :node/value "l"} {:node/name :dompa/text :node/value "d"}]}]}]}]} ($ "hello" (map (fn [x] ($ x)) ["w" (map (fn [x] ($ x)) ["o" "r" (map (fn [x] ($ x)) ["l" "d"])])])))))) (deftest nil-in-hierarchy-does-not-remove-siblings-test (testing "nil in a fragment should not remove sibling elements" (is (= "
one
two
" (nodes/->html [($ :<> ($ :div "one") ($ :div "two") nil)])))) (testing "nil between siblings should not affect them" (is (= "
one
two
" (nodes/->html [($ :<> ($ :div "one") nil ($ :div "two"))])))) (testing "multiple nils should not affect siblings" (is (= "
one
two
three
" (nodes/->html [($ :<> nil ($ :div "one") nil ($ :div "two") nil ($ :div "three") nil)])))) (testing "nil inside nested element should not affect parent siblings" (is (= "
hello
world
" (nodes/->html [($ :<> ($ :div ($ :span "hello") nil) ($ :div "world"))]))))) (deftest traverse-test (let [traverser-fn (fn [node] (if (= :dompa/text (:node/name node)) (assoc node :node/value "world hello") node))] (is (= "
world hello
" (-> (html/->nodes "
hello world
") (nodes/traverse traverser-fn) nodes/->html))))) (deftest zip-test (let [nodes (html/->nodes "

hello

world

") zipper (nodes/zip (first nodes))] (is (= :div (:node/name (zip/node zipper)))) (is (= "hello" (-> zipper zip/down zip/down zip/node :node/value)))))