{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE OverloadedStrings #-}
import Text.Hamlet.XML
import qualified Text.XML as X
import Test.HUnit
import Test.Hspec
import qualified Data.Map as Map
main :: IO ()
main = hspec $ do
describe "xml-hamlet" $ do
it "handles plain tags" $ [xml|
<foo>
<baz>
|] @?=
[ X.NodeElement $ X.Element "foo" Map.empty
[ X.NodeElement $ X.Element "baz" Map.empty []
]
]
it "handles raw text" $ [xml|
<foo>
<baz>bin
|] @?=
[ X.NodeElement $ X.Element "foo" Map.empty
[ X.NodeElement $ X.Element "baz" Map.empty
[ X.NodeContent "bin"
]
]
]
it "handles variables" $ [xml|
<foo>
<baz>#{bin}
|] @?=
[ X.NodeElement $ X.Element "foo" Map.empty
[ X.NodeElement $ X.Element "baz" Map.empty
[ X.NodeContent "bin"
]
]
]
it "handles embed" $ [xml|
<foo>
<baz>^{nodes}
|] @?=
[ X.NodeElement $ X.Element "foo" Map.empty
[ X.NodeElement $ X.Element "baz" Map.empty nodes
]
]
it "handles attributes" $ [xml|
<foo>
<bar here=there>
<baz>
|] @?=
[ X.NodeElement $ X.Element "foo" Map.empty
[ X.NodeElement $ X.Element "bar" (Map.singleton "here" "there")
[ X.NodeElement $ X.Element "baz" Map.empty []
]
]
]
it "handles attributes" $ [xml|
<foo>
<bar here=there>
<baz :False:false=false :True:true=#{true} *{attrs}>
|] @?=
[ X.NodeElement $ X.Element "foo" Map.empty
[ X.NodeElement $ X.Element "bar" (Map.singleton "here" "there")
[ X.NodeElement $ X.Element "baz" (Map.fromList (("true", "true") : attrs)) []
]
]
]
it "handles forall" $ [xml|
$forall x <- xs
<word>#{x}
|] @?=
[ X.NodeElement $ X.Element "word" Map.empty [X.NodeContent "foo"]
, X.NodeElement $ X.Element "word" Map.empty [X.NodeContent "bar"]
, X.NodeElement $ X.Element "word" Map.empty [X.NodeContent "baz"]
]
it "handles with" $ [xml|
$with ys <- xs
$forall x <- ys
<word>#{x}
|] @?=
[ X.NodeElement $ X.Element "word" Map.empty [X.NodeContent "foo"]
, X.NodeElement $ X.Element "word" Map.empty [X.NodeContent "bar"]
, X.NodeElement $ X.Element "word" Map.empty [X.NodeContent "baz"]
]
it "handles maybe" $ [xml|
$maybe _x <- Just five
<one>
$nothing
<two>
$maybe _x <- Nothing
<three>
$nothing
<four>
|] @?=
[ X.NodeElement $ X.Element "one" Map.empty []
, X.NodeElement $ X.Element "four" Map.empty []
]
it "handles conditionals" $ [xml|
$if True
<one>
$else
<two>
$if False
<three>
$elseif True
<four>
$if False
<five>
$elseif False
<six>
$else
<seven>
|] @?=
[ X.NodeElement $ X.Element "one" Map.empty []
, X.NodeElement $ X.Element "four" Map.empty []
, X.NodeElement $ X.Element "seven" Map.empty []
]
it "case on Maybe" $
let nothing = Nothing
justTrue = Just True
in [xml|
$case nothing
$of Just val
$of Nothing
<one>
$case justTrue
$of Just val
$if val
<two>
$of Nothing
$case (Just $ not False)
$of Nothing
$of Just val
$if val
<three>
$case Nothing
$of Just val
$of _
<four>
|] @?=
[ X.NodeElement $ X.Element "one" Map.empty []
, X.NodeElement $ X.Element "two" Map.empty []
, X.NodeElement $ X.Element "three" Map.empty []
, X.NodeElement $ X.Element "four" Map.empty []
]
it "recognizes clark notation" $ [xml|
<{foo}bar {baz}bin="x">
|] @?= [X.NodeElement $ X.Element "{foo}bar" (Map.singleton "{baz}bin" "x") []]
it "recognizes clark with URLs" $ [xml|
<{http://www.example.com/foo/bar}baz>
|] @?= [X.NodeElement $ X.Element "{http://www.example.com/foo/bar}baz" Map.empty []]
it "allow embedding comments" $[xml|^{comment}|] @?= comment
it "multiline tags" $ [xml|
<foo bar=baz
bin=bin>content
|] @?= [xml|<foo bar=baz bin=bin>content|]
it "short circuiting of attributes" $ [xml|<foo :False:x=#{undefined}>|] @?= [xml|<foo>|]
it "Hash in attribute value" $ [xml|<a href=#>|] @?= [xml|<a href="#">|]
where
bin = "bin"
nodes = [X.NodeInstruction $ X.Instruction "ifoo" "ibar"]
true = "true"
attrs = [("one","a"), ("two","b")]
xs = ["foo", "bar", "baz"]
comment = [X.NodeComment "somecomment"]
five :: Int
five = 5