(ns hiccup2.core-test (:require [clojure.test :refer :all] [hiccup2.core :refer :all] [hiccup.util :as util])) (deftest return-types #_(testing "html returns a RawString" (is (util/raw-string? (html [:div])))) (testing "converting to string" (= (str (html [:div])) "
"))) (deftest tag-names (testing "basic tags" (is (= (str (html [:div])) "
")) (is (= (str (html ["div"])) "
")) (is (= (str (html ['div])) "
"))) (testing "tag syntax sugar" (is (= (str (html [:div#foo])) "
")) (is (= (str (html [:div.foo])) "
")) (is (= (str (html [:div.foo (str "bar" "baz")])) "
barbaz
")) (is (= (str (html [:div.a.b])) "
")) (is (= (str (html [:div.a.b.c])) "
")) (is (= (str (html [:div#foo.bar.baz])) "
")))) (deftest tag-contents (testing "empty tags" (is (= (str (html [:div])) "
")) (is (= (str (html [:h1])) "

")) (is (= (str (html [:script])) "")) (is (= (str (html [:text])) "")) (is (= (str (html [:a])) "")) (is (= (str (html [:iframe])) "")) (is (= (str (html [:title])) "")) (is (= (str (html [:section])) "
")) (is (= (str (html [:select])) "")) (is (= (str (html [:object])) "")) (is (= (str (html [:video])) ""))) (testing "void tags" (is (= (str (html [:br])) "
")) (is (= (str (html [:link])) "")) (is (= (str (html [:colgroup {:span 2}])) "")) (is (= (str (html [:colgroup [:col]])) ""))) (testing "tags containing text" (is (= (str (html [:text "Lorem Ipsum"])) "Lorem Ipsum"))) (testing "contents are concatenated" (is (= (str (html [:body "foo" "bar"])) "foobar")) (is (= (str (html [:body [:p] [:br]])) "


"))) (testing "seqs are expanded" (is (= (str (html [:body (list "foo" "bar")])) "foobar")) (is (= (str (html (list [:p "a"] [:p "b"]))) "

a

b

"))) (testing "keywords are turned into strings" (is (= (str (html [:div :foo])) "
foo
"))) (testing "vecs don't expand - error if vec doesn't have tag name" (is (thrown? IllegalArgumentException (html (vector [:p "a"] [:p "b"]))))) (testing "tags can contain tags" (is (= (str (html [:div [:p]])) "

")) (is (= (str (html [:div [:b]])) "
")) (is (= (str (html [:p [:span [:a "foo"]]])) "

foo

")))) (deftest tag-attributes (testing "tag with blank attribute map" (is (= (str (html [:xml {}])) ""))) (testing "tag with populated attribute map" (is (= (str (html [:xml {:a "1", :b "2"}])) "")) (is (= (str (html [:img {"id" "foo"}])) "")) (is (= (str (html [:img {'id "foo"}])) "")) (is (= (str (html [:xml {:a "1", 'b "2", "c" "3"}])) ""))) (testing "attribute values are escaped" (is (= (str (html [:div {:id "\""}])) "
"))) (testing "boolean attributes" (is (= (str (html [:input {:type "checkbox" :checked true}])) "")) (is (= (str (html [:input {:type "checkbox" :checked false}])) ""))) (testing "nil attributes" (is (= (str (html [:span {:class nil} "foo"])) "foo"))) (testing "vector attributes" (is (= (str (html [:span {:class ["bar" "baz"]} "foo"])) "foo")) (is (= (str (html [:span {:class ["baz"]} "foo"])) "foo")) (is (= (str (html [:span {:class "baz bar"} "foo"])) "foo"))) (testing "map attributes" (is (= (str (html [:span {:style {:color "red" :opacity "100%"}} "foo"])) "foo"))) (testing "resolving conflicts between attributes in the map and tag" (is (= (str (html [:div.foo {:class "bar"} "baz"])) "
baz
")) (is (= (str (html [:div.foo {:class ["bar"]} "baz"])) "
baz
")) (is (= (str (html [:div#bar.foo {:id "baq"} "baz"])) "
baz
")))) (deftest compiled-tags (testing "tag content can be vars" (is (= (let [x "foo"] (str (html [:span x]))) "foo"))) (testing "tag content can be forms" (is (= (str (html [:span (str (+ 1 1))])) "2")) (is (= (str (html [:span ({:foo "bar"} :foo)])) "bar"))) (testing "attributes can contain vars" (let [x "foo"] (is (= (str (html [:xml {:x x}])) "")) (is (= (str (html [:xml {x "x"}])) "")) (is (= (str (html [:xml {:x x} "bar"])) "bar")))) (testing "attributes are evaluated" (is (= (str (html [:img {:src (str "/foo" "/bar")}])) "")) (is (= (str (html [:div {:id (str "a" "b")} (str "foo")])) "
foo
"))) (testing "type hints" (let [string "x"] (is (= (str (html [:span ^String string])) "x")))) (testing "optimized forms" (is (= (str (html [:ul (for [n (range 3)] [:li n])])) "")) (is (= (str (html [:div (if true [:span "foo"] [:span "bar"])])) "
foo
"))) (testing "values are evaluated only once" (let [times-called (atom 0) foo #(swap! times-called inc)] (html [:div (foo)]) (is (= @times-called 1))))) (deftest render-modes (testing "closed tag" (is (= (str (html [:p] [:br])) "


")) (is (= (str (html {:mode :xhtml} [:p] [:br])) "


")) (is (= (str (html {:mode :html} [:p] [:br])) "


")) (is (= (str (html {:mode :xml} [:p] [:br])) "


")) (is (= (str (html {:mode :sgml} [:p] [:br])) "


"))) (testing "boolean attributes" (is (= (str (html {:mode :xml} [:input {:type "checkbox" :checked true}])) "")) (is (= (str (html {:mode :sgml} [:input {:type "checkbox" :checked true}])) ""))) (testing "laziness and binding scope" (is (= (str (html {:mode :sgml} [:html [:link] (list [:link])])) ""))) (testing "function binding scope" (let [f #(html [:p "<>" [:br]])] (is (= (str (html (f))) "

<>

")) (is (= (str (html {:escape-strings? false} (f))) "

<>

")) (is (= (str (html {:mode :html} (f))) "

<>

")) (is (= (str (html {:escape-strings? false, :mode :html} (f))) "

<>

"))))) (deftest auto-escaping (testing "literals" (is (= (str (html "<>")) "<>")) (is (= (str (html :<>)) "<>")) (is (= (str (html ^String (str "<>"))) "<>")) (is (= (str (html {} {"" ""})) "{"<a>" "<b>"}")) (is (= (str (html #{"<>"})) "#{"<>"}")) (is (= (str (html 1)) "1")) (is (= (str (html ^Number (+ 1 1))) "2"))) (testing "non-literals" (is (= (str (html (list [:p ""] [:p ""]))) "

<foo>

<bar>

")) (is (= (str (html ((constantly "")))) "<foo>")) (is (= (let [x ""] (str (html x))) "<foo>"))) (testing "optimized forms" (is (= (str (html (if true : :))) "<foo>")) (is (= (str (html (for [x [:]] x))) "<foo>"))) (testing "elements" (is (= (str (html [:p "<>"])) "

<>

")) (is (= (str (html [:p :<>])) "

<>

")) (is (= (str (html [:p {} {"" ""}])) "

{"<foo>" "<bar>"}

")) (is (= (str (html [:p {} #{""}])) "

#{"<foo>"}

")) (is (= (str (html [:p {:class "<\">"}])) "

")) (is (= (str (html [:p {:class ["<\">"]}])) "

")) (is (= (str (html [:ul [:li ""]])) "
  • <foo>
"))) (testing "raw strings" #_(is (= (str (html (util/raw-string ""))) "")) (is (= (str (html [:p (util/raw-string "")])) "

")) (is (= (str (html (html [:p "<>"]))) "

<>

")) (is (= (str (html [:ul (html [:li "<>"])])) "
  • <>
")))) (deftest html-escaping (testing "precompilation" (is (= (str (html {:escape-strings? true} [:p "<>"])) "

<>

")) (is (= (str (html {:escape-strings? false} [:p "<>"])) "

<>

"))) (testing "dynamic generation" (let [x [:p "<>"]] (is (= (str (html {:escape-strings? true} x)) "

<>

")) (is (= (str (html {:escape-strings? false} x)) "

<>

")))) (testing "attributes" (is (= (str (html {:escape-strings? true} [:p {:class "<>"}])) "

")) (is (= (str (html {:escape-strings? false} [:p {:class "<>"}])) "

"))) (testing "raw strings" (is (= (str (html {:escape-strings? true} [:p (util/raw-string "<>")])) "

<>

")) (is (= (str (html {:escape-strings? false} [:p (util/raw-string "<>")])) "

<>

")) #_(is (= (str (html {:escape-strings? true} [:p (raw "<>")])) "

<>

")) #_(is (= (str (html {:escape-strings? false} [:p (raw "<>")])) "

<>

"))))