Blame test/main.hs

Packit 899799
{-# LANGUAGE DeriveDataTypeable #-}
Packit 899799
{-# LANGUAGE OverloadedStrings  #-}
Packit 899799
Packit 899799
import           Control.Exception            (Exception, toException)
Packit 899799
import           Control.Monad.IO.Class       (liftIO)
Packit 899799
import qualified Data.ByteString.Char8        as S
Packit 899799
import qualified Data.ByteString.Lazy.Char8   as L
Packit 899799
import           Data.Typeable                (Typeable)
Packit 899799
import           Data.XML.Types
Packit 899799
import           Test.Hspec
Packit 899799
import           Test.HUnit                   hiding (Test)
Packit 899799
import qualified Text.XML                     as Res
Packit 899799
import qualified Text.XML.Cursor              as Cu
Packit 899799
import           Text.XML.Stream.Parse        (def)
Packit 899799
import qualified Text.XML.Stream.Parse        as P
Packit 899799
import qualified Text.XML.Unresolved          as D
Packit 899799
Packit 899799
import           Control.Applicative          ((<$>))
Packit 899799
import           Control.Monad
Packit 899799
import           Control.Monad.Trans.Class    (lift)
Packit 899799
import qualified Data.Set                     as Set
Packit 899799
import           Data.Text                    (Text)
Packit 899799
import qualified Data.Text                    as T
Packit 899799
import           Text.XML.Cursor              (($.//), ($/), ($//), ($|),
Packit 899799
                                               (&.//), (&/), (&//))
Packit 899799
Packit 899799
import           Control.Monad.Trans.Resource (runResourceT)
Packit 899799
import qualified Control.Monad.Trans.Resource as C
Packit 899799
import           Data.Conduit                 ((=$=))
Packit 899799
import qualified Data.Conduit                 as C
Packit 899799
import qualified Data.Conduit.List            as CL
Packit 899799
import qualified Data.Map                     as Map
Packit 899799
import           Text.Blaze                   (toMarkup)
Packit 899799
import           Text.Blaze.Renderer.String   (renderMarkup)
Packit 899799
Packit 899799
main :: IO ()
Packit 899799
main = hspec $ do
Packit 899799
    describe "XML parsing and rendering" $ do
Packit 899799
        it "is idempotent to parse and render a document" documentParseRender
Packit 899799
        it "has valid parser combinators" combinators
Packit 899799
        context "has working choose function" testChoose
Packit 899799
        it "has working many function" testMany
Packit 899799
        it "has working many' function" testMany'
Packit 899799
        it "has working manyYield function" testManyYield
Packit 899799
        it "has working takeContent function" testTakeContent
Packit 899799
        it "has working takeTree function" testTakeTree
Packit 899799
        it "has working takeAnyTreeContent function" testTakeAnyTreeContent
Packit 899799
        it "has working orE" testOrE
Packit 899799
        it "is idempotent to parse and pretty render a document" documentParsePrettyRender
Packit 899799
        it "ignores the BOM" parseIgnoreBOM
Packit 899799
        it "strips duplicated attributes" stripDuplicateAttributes
Packit 899799
        it "displays comments" testRenderComments
Packit 899799
        it "conduit parser" testConduitParser
Packit 899799
        it "can omit the XML declaration" omitXMLDeclaration
Packit 899799
        context "correctly parses hexadecimal entities" hexEntityParsing
Packit 899799
    describe "XML Cursors" $ do
Packit 899799
        it "has correct parent" cursorParent
Packit 899799
        it "has correct ancestor" cursorAncestor
Packit 899799
        it "has correct orSelf" cursorOrSelf
Packit 899799
        it "has correct preceding" cursorPreceding
Packit 899799
        it "has correct following" cursorFollowing
Packit 899799
        it "has correct precedingSibling" cursorPrecedingSib
Packit 899799
        it "has correct followingSibling" cursorFollowingSib
Packit 899799
        it "has correct descendant" cursorDescendant
Packit 899799
        it "has correct check" cursorCheck
Packit 899799
        it "has correct check with lists" cursorPredicate
Packit 899799
        it "has correct checkNode" cursorCheckNode
Packit 899799
        it "has correct checkElement" cursorCheckElement
Packit 899799
        it "has correct checkName" cursorCheckName
Packit 899799
        it "has correct anyElement" cursorAnyElement
Packit 899799
        it "has correct element" cursorElement
Packit 899799
        it "has correct laxElement" cursorLaxElement
Packit 899799
        it "has correct content" cursorContent
Packit 899799
        it "has correct attribute" cursorAttribute
Packit 899799
        it "has correct laxAttribute" cursorLaxAttribute
Packit 899799
        it "has correct &* and $* operators" cursorDeep
Packit 899799
        it "has correct force" cursorForce
Packit 899799
        it "has correct forceM" cursorForceM
Packit 899799
        it "has correct hasAttribute" cursorHasAttribute
Packit 899799
        it "has correct attributeIs" cursorAttributeIs
Packit 899799
    describe "resolved" $ do
Packit 899799
        it "identifies unresolved entities" resolvedIdentifies
Packit 899799
        it "decodeHtmlEntities" testHtmlEntities
Packit 899799
        it "works for resolvable entities" resolvedAllGood
Packit 899799
        it "merges adjacent content nodes" resolvedMergeContent
Packit 899799
        it "understands inline entity declarations" resolvedInline
Packit 899799
    describe "pretty" $ do
Packit 899799
        it "works" casePretty
Packit 899799
    describe "top level namespaces" $ do
Packit 899799
        it "works" caseTopLevelNamespace
Packit 899799
        it "works with prefix" caseTopLevelNamespacePrefix
Packit 899799
        it "handles conflicts" caseTLNConflict
Packit 899799
    describe "blaze-html instances" $ do
Packit 899799
        it "works" caseBlazeHtml
Packit 899799
    describe "attribute reordering" $ do
Packit 899799
        it "works" caseAttrReorder
Packit 899799
    describe "ordering attributes explicitly" $ do
Packit 899799
        it "works" caseOrderAttrs
Packit 899799
    it "parsing CDATA" caseParseCdata
Packit 899799
    it "retains namespaces when asked" caseRetainNamespaces
Packit 899799
    it "handles iso-8859-1" caseIso8859_1
Packit 899799
    it "renders CDATA when asked" caseRenderCDATA
Packit 899799
    it "escapes CDATA closing tag in CDATA" caseEscapesCDATA
Packit 899799
Packit 899799
documentParseRender :: IO ()
Packit 899799
documentParseRender =
Packit 899799
    mapM_ go docs
Packit 899799
  where
Packit 899799
    go x = x @=? D.parseLBS_ def (D.renderLBS def x)
Packit 899799
    docs =
Packit 899799
        [ Document (Prologue [] Nothing [])
Packit 899799
                   (Element "foo" [] [])
Packit 899799
                   []
Packit 899799
        , D.parseLBS_ def
Packit 899799
            "\n<foo/>"
Packit 899799
        , D.parseLBS_ def
Packit 899799
            "\n<foo><nested>&ignore;</nested></foo>"
Packit 899799
        , D.parseLBS_ def
Packit 899799
            "<foo>]]></foo>"
Packit 899799
        , D.parseLBS_ def
Packit 899799
            "<foo bar='baz&bin'/>"
Packit 899799
        , D.parseLBS_ def
Packit 899799
            "<foo></foo>"
Packit 899799
        , D.parseLBS_ def
Packit 899799
            "<foo></foo>"
Packit 899799
        ]
Packit 899799
Packit 899799
documentParsePrettyRender :: IO ()
Packit 899799
documentParsePrettyRender =
Packit 899799
    L.unpack (D.renderLBS def { D.rsPretty = True } (D.parseLBS_ def doc)) @?= L.unpack doc
Packit 899799
  where
Packit 899799
    doc = L.unlines
Packit 899799
        [ ""
Packit 899799
        , "<foo>"
Packit 899799
        , "    "
Packit 899799
        , "    text"
Packit 899799
        , "    "
Packit 899799
        , "</foo>"
Packit 899799
        ]
Packit 899799
Packit 899799
combinators :: Assertion
Packit 899799
combinators = runResourceT $ P.parseLBS def input C.$$ do
Packit 899799
    P.force "need hello" $ P.tag' "hello" (P.requireAttr "world") $ \world -> do
Packit 899799
        liftIO $ world @?= "true"
Packit 899799
        P.force "need child1" $ P.tagNoAttr "{mynamespace}child1" $ return ()
Packit 899799
        P.force "need child2" $ P.tagNoAttr "child2" $ return ()
Packit 899799
        P.force "need child3" $ P.tagNoAttr "child3" $ do
Packit 899799
            x <- P.contentMaybe
Packit 899799
            liftIO $ x @?= Just "combine <all> &content"
Packit 899799
  where
Packit 899799
    input = L.concat
Packit 899799
        [ ""
Packit 899799
        , "\n"
Packit 899799
        , "<hello world='true'>"
Packit 899799
        , ""
Packit 899799
        , "<child1 xmlns='mynamespace'/>"
Packit 899799
        , ""
Packit 899799
        , "<child2>   </child2>"
Packit 899799
        , "<child3>combine <all> </child3>\n"
Packit 899799
        , "</hello>"
Packit 899799
        ]
Packit 899799
Packit 899799
testChoose :: Spec
Packit 899799
testChoose = do
Packit 899799
    it "can choose between elements"
Packit 899799
        testChooseEitherElem
Packit 899799
    it "can choose between elements and text, returning text"
Packit 899799
        testChooseElemOrTextIsText
Packit 899799
    it "can choose between elements and text, returning elements"
Packit 899799
        testChooseElemOrTextIsElem
Packit 899799
    it "can choose between text and elements, returning text"
Packit 899799
        testChooseTextOrElemIsText
Packit 899799
    it "can choose between text and elements, returning elements"
Packit 899799
        testChooseTextOrElemIsElem
Packit 899799
    it "can choose between text and elements, when the text is encoded"
Packit 899799
        testChooseElemOrTextIsEncoded
Packit 899799
    it "can choose between text and elements, when the text is encoded, NBSP"
Packit 899799
        testChooseElemOrTextIsEncodedNBSP
Packit 899799
    it "can choose between elements and text, when the text is whitespace"
Packit 899799
        testChooseElemOrTextIsWhiteSpace
Packit 899799
    it "can choose between text and elements, when the text is whitespace"
Packit 899799
        testChooseTextOrElemIsWhiteSpace
Packit 899799
    it "can choose between text and elements, when the whitespace is both literal and encoded"
Packit 899799
        testChooseElemOrTextIsChunkedText
Packit 899799
    it "can choose between text and elements, when the text is chunked the other way"
Packit 899799
        testChooseElemOrTextIsChunkedText2
Packit 899799
Packit 899799
testChooseElemOrTextIsText :: Assertion
Packit 899799
testChooseElemOrTextIsText = runResourceT $ P.parseLBS def input C.$$ do
Packit 899799
    P.force "need hello" $ P.tagNoAttr "hello" $ do
Packit 899799
        x <- P.choose
Packit 899799
            [ P.tagNoAttr "failure" $ return "boom"
Packit 899799
            , P.contentMaybe
Packit 899799
            ]
Packit 899799
        liftIO $ x @?= Just " something "
Packit 899799
  where
Packit 899799
    input = L.concat
Packit 899799
        [ ""
Packit 899799
        , "\n"
Packit 899799
        , "<hello>"
Packit 899799
        , " something "
Packit 899799
        , "</hello>"
Packit 899799
        ]
Packit 899799
Packit 899799
testChooseElemOrTextIsEncoded :: Assertion
Packit 899799
testChooseElemOrTextIsEncoded = runResourceT $ P.parseLBS def input C.$$ do
Packit 899799
    P.force "need hello" $ P.tagNoAttr "hello" $ do
Packit 899799
        x <- P.choose
Packit 899799
            [ P.tagNoAttr "failure" $ return "boom"
Packit 899799
            , P.contentMaybe
Packit 899799
            ]
Packit 899799
        liftIO $ x @?= Just "\x20something\x20"
Packit 899799
  where
Packit 899799
    input = L.concat
Packit 899799
        [ ""
Packit 899799
        , "\n"
Packit 899799
        , "<hello>"
Packit 899799
        , " something "
Packit 899799
        , "</hello>"
Packit 899799
        ]
Packit 899799
Packit 899799
testChooseElemOrTextIsEncodedNBSP :: Assertion
Packit 899799
testChooseElemOrTextIsEncodedNBSP = runResourceT $ P.parseLBS def input C.$$ do
Packit 899799
    P.force "need hello" $ P.tagNoAttr "hello" $ do
Packit 899799
        x <- P.choose
Packit 899799
            [ P.tagNoAttr "failure" $ return "boom"
Packit 899799
            , P.contentMaybe
Packit 899799
            ]
Packit 899799
        liftIO $ x @?= Just "\160something\160"
Packit 899799
  where
Packit 899799
    input = L.concat
Packit 899799
        [ ""
Packit 899799
        , "\n"
Packit 899799
        , "<hello>"
Packit 899799
        , " something "
Packit 899799
        , "</hello>"
Packit 899799
        ]
Packit 899799
Packit 899799
Packit 899799
testChooseElemOrTextIsWhiteSpace :: Assertion
Packit 899799
testChooseElemOrTextIsWhiteSpace = runResourceT $ P.parseLBS def input C.$$ do
Packit 899799
    P.force "need hello" $ P.tagNoAttr "hello" $ do
Packit 899799
        x <- P.choose
Packit 899799
            [ P.tagNoAttr "failure" $ return "boom"
Packit 899799
            , P.contentMaybe
Packit 899799
            ]
Packit 899799
        liftIO $ x @?= Just "\x20\x20\x20"
Packit 899799
  where
Packit 899799
    input = L.concat
Packit 899799
        [ ""
Packit 899799
        , "\n"
Packit 899799
        , "<hello>   </hello>"
Packit 899799
        ]
Packit 899799
Packit 899799
testChooseTextOrElemIsWhiteSpace :: Assertion
Packit 899799
testChooseTextOrElemIsWhiteSpace = runResourceT $ P.parseLBS def input C.$$ do
Packit 899799
    P.force "need hello" $ P.tagNoAttr "hello" $ do
Packit 899799
        x <- P.choose
Packit 899799
            [ P.contentMaybe
Packit 899799
            , P.tagNoAttr "failure" $ return "boom"
Packit 899799
            ]
Packit 899799
        liftIO $ x @?= Just "\x20\x20\x20"
Packit 899799
  where
Packit 899799
    input = L.concat
Packit 899799
        [ ""
Packit 899799
        , "\n"
Packit 899799
        , "<hello>   </hello>"
Packit 899799
        ]
Packit 899799
Packit 899799
testChooseElemOrTextIsChunkedText :: Assertion
Packit 899799
testChooseElemOrTextIsChunkedText = runResourceT $ P.parseLBS def input C.$$ do
Packit 899799
    P.force "need hello" $ P.tagNoAttr "hello" $ do
Packit 899799
        x <- P.choose
Packit 899799
            [ P.tagNoAttr "failure" $ return "boom"
Packit 899799
            , P.contentMaybe
Packit 899799
            ]
Packit 899799
        liftIO $ x @?= Just "\x20\x20\x20"
Packit 899799
  where
Packit 899799
    input = L.concat
Packit 899799
        [ ""
Packit 899799
        , "\n"
Packit 899799
        , "<hello>   </hello>"
Packit 899799
        ]
Packit 899799
Packit 899799
testChooseElemOrTextIsChunkedText2 :: Assertion
Packit 899799
testChooseElemOrTextIsChunkedText2 = runResourceT $ P.parseLBS def input C.$$ do
Packit 899799
    P.force "need hello" $ P.tagNoAttr "hello" $ do
Packit 899799
        x <- P.choose
Packit 899799
            [ P.tagNoAttr "failure" $ return "boom"
Packit 899799
            , P.contentMaybe
Packit 899799
            ]
Packit 899799
        liftIO $ x @?= Just "\x20\x20\x20"
Packit 899799
  where
Packit 899799
    input = L.concat
Packit 899799
        [ ""
Packit 899799
        , "\n"
Packit 899799
        , "<hello>   </hello>"
Packit 899799
        ]
Packit 899799
Packit 899799
testChooseElemOrTextIsElem :: Assertion
Packit 899799
testChooseElemOrTextIsElem = runResourceT $ P.parseLBS def input C.$$ do
Packit 899799
    P.force "need hello" $ P.tagNoAttr "hello" $ do
Packit 899799
        x <- P.choose
Packit 899799
            [ P.tagNoAttr "success" $ return "success"
Packit 899799
            , P.contentMaybe
Packit 899799
            ]
Packit 899799
        liftIO $ x @?= Just "success"
Packit 899799
  where
Packit 899799
    input = L.concat
Packit 899799
        [ ""
Packit 899799
        , "\n"
Packit 899799
        , "<hello>"
Packit 899799
        , "<success/>"
Packit 899799
        , "</hello>"
Packit 899799
        ]
Packit 899799
Packit 899799
testChooseTextOrElemIsText :: Assertion
Packit 899799
testChooseTextOrElemIsText = runResourceT $ P.parseLBS def input C.$$ do
Packit 899799
    P.force "need hello" $ P.tagNoAttr "hello" $ do
Packit 899799
        x <- P.choose
Packit 899799
            [ P.contentMaybe
Packit 899799
            , P.tagNoAttr "failure" $ return "boom"
Packit 899799
            ]
Packit 899799
        liftIO $ x @?= Just " something "
Packit 899799
  where
Packit 899799
    input = L.concat
Packit 899799
        [ ""
Packit 899799
        , "\n"
Packit 899799
        , "<hello>"
Packit 899799
        , " something "
Packit 899799
        , "</hello>"
Packit 899799
        ]
Packit 899799
Packit 899799
testChooseTextOrElemIsElem :: Assertion
Packit 899799
testChooseTextOrElemIsElem = runResourceT $ P.parseLBS def input C.$$ do
Packit 899799
    P.force "need hello" $ P.tagNoAttr "hello" $ do
Packit 899799
        x <- P.choose
Packit 899799
            [ P.contentMaybe
Packit 899799
            , P.tagNoAttr "success" $ return "success"
Packit 899799
            ]
Packit 899799
        liftIO $ x @?= Just "success"
Packit 899799
  where
Packit 899799
    input = L.concat
Packit 899799
        [ ""
Packit 899799
        , "\n"
Packit 899799
        , "<hello>"
Packit 899799
        , "<success/>"
Packit 899799
        , "</hello>"
Packit 899799
        ]
Packit 899799
Packit 899799
testChooseEitherElem :: Assertion
Packit 899799
testChooseEitherElem = runResourceT $ P.parseLBS def input C.$$ do
Packit 899799
    P.force "need hello" $ P.tagNoAttr "hello" $ do
Packit 899799
        x <- P.choose
Packit 899799
            [ P.tagNoAttr "failure" $ return 1
Packit 899799
            , P.tagNoAttr "success" $ return 2
Packit 899799
            ]
Packit 899799
        liftIO $ x @?= Just (2 :: Int)
Packit 899799
  where
Packit 899799
    input = L.concat
Packit 899799
        [ ""
Packit 899799
        , "\n"
Packit 899799
        , "<hello>"
Packit 899799
        , "<success/>"
Packit 899799
        , "</hello>"
Packit 899799
        ]
Packit 899799
Packit 899799
testManyYield :: Assertion
Packit 899799
testManyYield = do
Packit 899799
    -- Basically the same as testMany, but consume the streamed result
Packit 899799
    result <- runResourceT $
Packit 899799
        P.parseLBS def input C.$$ helloParser
Packit 899799
        =$= CL.consume
Packit 899799
    length result @?= 5
Packit 899799
  where
Packit 899799
    helloParser = void $ P.tagNoAttr "hello" $ P.manyYield successParser
Packit 899799
    successParser = P.tagNoAttr "success" $ return ()
Packit 899799
    input = L.concat
Packit 899799
        [ ""
Packit 899799
        , "\n"
Packit 899799
        , "<hello>"
Packit 899799
        , "<success/>"
Packit 899799
        , "<success/>"
Packit 899799
        , "<success/>"
Packit 899799
        , "<success/>"
Packit 899799
        , "<success/>"
Packit 899799
        , "</hello>"
Packit 899799
        ]
Packit 899799
Packit 899799
testTakeContent :: Assertion
Packit 899799
testTakeContent = do
Packit 899799
    result <- runResourceT $ P.parseLBS def input C.$$ rootParser
Packit 899799
    result @?= Just
Packit 899799
      [ EventContent (ContentText "Hello world !")
Packit 899799
      ]
Packit 899799
  where
Packit 899799
    rootParser = P.tagNoAttr "root" $ void (P.takeContent >> P.takeContent) =$= CL.consume
Packit 899799
    input = L.concat
Packit 899799
        [ ""
Packit 899799
        , "\n"
Packit 899799
        , "<root>"
Packit 899799
        , "Hello world !"
Packit 899799
        , "</root>"
Packit 899799
        ]
Packit 899799
Packit 899799
testTakeTree :: Assertion
Packit 899799
testTakeTree = do
Packit 899799
    result <- runResourceT $ P.parseLBS def input C.$$ rootParser
Packit 899799
    result @?=
Packit 899799
      [ EventBeginDocument
Packit 899799
      , EventBeginDoctype "foo" Nothing
Packit 899799
      , EventEndDoctype
Packit 899799
      , EventBeginElement "a" []
Packit 899799
      , EventBeginElement "em" []
Packit 899799
      , EventContent (ContentText "Hello world !")
Packit 899799
      , EventEndElement "em"
Packit 899799
      , EventEndElement "a"
Packit 899799
      ]
Packit 899799
  where
Packit 899799
    rootParser = void (P.takeTree "a" P.ignoreAttrs) =$= CL.consume
Packit 899799
    input = L.concat
Packit 899799
        [ ""
Packit 899799
        , "\n"
Packit 899799
        , ""
Packit 899799
        , "Hello world !"
Packit 899799
        , ""
Packit 899799
        , ""
Packit 899799
        , ""
Packit 899799
        ]
Packit 899799
Packit 899799
testTakeAnyTreeContent :: Assertion
Packit 899799
testTakeAnyTreeContent = do
Packit 899799
    result <- runResourceT $ P.parseLBS def input C.$$ rootParser
Packit 899799
    result @?= Just
Packit 899799
      [ EventBeginElement "b" []
Packit 899799
      , EventContent (ContentText "Hello ")
Packit 899799
      , EventBeginElement "em" []
Packit 899799
      , EventContent (ContentText "world")
Packit 899799
      , EventEndElement "em"
Packit 899799
      , EventContent (ContentText " !")
Packit 899799
      , EventEndElement "b"
Packit 899799
      ]
Packit 899799
  where
Packit 899799
    rootParser = P.tagNoAttr "root" $ (P.takeAnyTreeContent >> void P.ignoreAnyTreeContent) =$= CL.consume
Packit 899799
    input = L.concat
Packit 899799
        [ ""
Packit 899799
        , "\n"
Packit 899799
        , "<root>"
Packit 899799
        , "Hello world ! Welcome !"
Packit 899799
        , "</root>"
Packit 899799
        ]
Packit 899799
Packit 899799
Packit 899799
testMany :: Assertion
Packit 899799
testMany = runResourceT $ P.parseLBS def input C.$$ do
Packit 899799
    P.force "need hello" $ P.tagNoAttr "hello" $ do
Packit 899799
        x <- P.many $ P.tagNoAttr "success" $ return ()
Packit 899799
        liftIO $ length x @?= 5
Packit 899799
  where
Packit 899799
    input = L.concat
Packit 899799
        [ ""
Packit 899799
        , "\n"
Packit 899799
        , "<hello>"
Packit 899799
        , "<success/>"
Packit 899799
        , "<success/>"
Packit 899799
        , "<success/>"
Packit 899799
        , "<success/>"
Packit 899799
        , "<success/>"
Packit 899799
        , "</hello>"
Packit 899799
        ]
Packit 899799
Packit 899799
testMany' :: Assertion
Packit 899799
testMany' = runResourceT $ P.parseLBS def input C.$$ do
Packit 899799
    P.force "need hello" $ P.tagNoAttr "hello" $ do
Packit 899799
        x <- P.many' $ P.tagNoAttr "success" $ return ()
Packit 899799
        liftIO $ length x @?= 5
Packit 899799
  where
Packit 899799
    input = L.concat
Packit 899799
        [ ""
Packit 899799
        , "\n"
Packit 899799
        , "<hello>"
Packit 899799
        , "<success/>"
Packit 899799
        , "<success/>"
Packit 899799
        , "<success/>"
Packit 899799
        , "<foobar/>"
Packit 899799
        , "<success/>"
Packit 899799
        , "<foo><bar attr=\"1\">some content</bar></foo>"
Packit 899799
        , "<success/>"
Packit 899799
        , "</hello>"
Packit 899799
        ]
Packit 899799
Packit 899799
testOrE :: IO ()
Packit 899799
testOrE = runResourceT $ P.parseLBS def input C.$$ do
Packit 899799
    P.force "need hello" $ P.tagNoAttr "hello" $ do
Packit 899799
        x <- P.tagNoAttr "failure" (return 1) `P.orE`
Packit 899799
             P.tagNoAttr "success" (return 2)
Packit 899799
        y <- P.tag' "success" (P.requireAttr "failure") (const $ return 1) `P.orE`
Packit 899799
             P.tag' "success" (P.requireAttr "success") (const $ return 2)
Packit 899799
        liftIO $ x @?= Just (2 :: Int)
Packit 899799
        liftIO $ y @?= Just (2 :: Int)
Packit 899799
  where
Packit 899799
    input = L.concat
Packit 899799
        [ ""
Packit 899799
        , "\n"
Packit 899799
        , "<hello>"
Packit 899799
        , "<success/>"
Packit 899799
        , "<success success=\"0\"/>"
Packit 899799
        , "</hello>"
Packit 899799
        ]
Packit 899799
Packit 899799
testConduitParser :: Assertion
Packit 899799
testConduitParser = runResourceT $ do
Packit 899799
    x <- P.parseLBS def input
Packit 899799
        C.$$ (P.force "need hello" $ P.tagNoAttr "hello" f)
Packit 899799
        =$= CL.consume
Packit 899799
    liftIO $ x @?= [1, 1, 1]
Packit 899799
  where
Packit 899799
    input = L.concat
Packit 899799
        [ ""
Packit 899799
        , "\n"
Packit 899799
        , "<hello>"
Packit 899799
        , "<item/>"
Packit 899799
        , "<item/>"
Packit 899799
        , "<item/>"
Packit 899799
        , "</hello>"
Packit 899799
        ]
Packit 899799
    f :: C.MonadThrow m => C.Conduit Event m Int
Packit 899799
    f = do
Packit 899799
        ma <- P.tagNoAttr "item" (return 1)
Packit 899799
        maybe (return ()) (\a -> C.yield a >> f) ma
Packit 899799
Packit 899799
omitXMLDeclaration :: Assertion
Packit 899799
omitXMLDeclaration = Res.renderLBS settings input @?= spec
Packit 899799
  where
Packit 899799
    settings = def { Res.rsXMLDeclaration = False }
Packit 899799
    input = Res.Document (Prologue [] Nothing [])
Packit 899799
              (Res.Element "foo" Map.empty [Res.NodeContent "bar"])
Packit 899799
              []
Packit 899799
    spec = "<foo>bar</foo>"
Packit 899799
Packit 899799
hexEntityParsing :: Spec
Packit 899799
hexEntityParsing = do
Packit 899799
  it "rejects leading 0x" $
Packit 899799
    go "<foo>&#x0xff;</foo>" @?= Nothing
Packit 899799
  it "rejects leading 0X" $
Packit 899799
    go "<foo>&#x0Xff;</foo>" @?= Nothing
Packit 899799
  it "accepts lowercase hex digits" $
Packit 899799
    go "<foo>ÿ</foo>" @?= Just spec
Packit 899799
  it "accepts uppercase hex digits" $
Packit 899799
    go "<foo>ÿ</foo>" @?= Just spec
Packit 899799
  --Note: this must be rejected, because, according to the XML spec, a
Packit 899799
  --legal EntityRef's entity matches Name, which can't start with a
Packit 899799
  --hash.
Packit 899799
  it "rejects trailing junk" $
Packit 899799
    go "<foo>&#xffhello;</foo>" @?= Nothing
Packit 899799
  --Some of these next tests are XML 1.0 specific (i.e., they would
Packit 899799
  --differ for XML 1.1), but approximately no-one uses XML 1.1.
Packit 899799
  it "rejects illegal character #x0" $
Packit 899799
    go "<foo>�</foo>" @?= Nothing
Packit 899799
  it "rejects illegal character #xFFFE" $
Packit 899799
    go "<foo>￾</foo>" @?= Nothing
Packit 899799
  it "rejects illegal character #xFFFF" $
Packit 899799
    go "<foo>￿</foo>" @?= Nothing
Packit 899799
  it "rejects illegal character #xD900" $
Packit 899799
    go "<foo>�</foo>" @?= Nothing
Packit 899799
  it "rejects illegal character #xC" $
Packit 899799
    go "<foo></foo>" @?= Nothing
Packit 899799
  it "rejects illegal character #x1F" $
Packit 899799
    go "<foo></foo>" @?= Nothing
Packit 899799
  it "accepts astral plane character" $
Packit 899799
    go "<foo>􀛿</foo>" @?= Just astralSpec
Packit 899799
  where
Packit 899799
    spec = Document (Prologue [] Nothing [])
Packit 899799
                    (Element "foo" [] [NodeContent (ContentText "\xff")])
Packit 899799
                    []
Packit 899799
Packit 899799
    astralSpec = Document (Prologue [] Nothing [])
Packit 899799
                    (Element "foo" [] [NodeContent (ContentText "\x1006ff")])
Packit 899799
                    []
Packit 899799
Packit 899799
    go = either (const Nothing) Just . D.parseLBS def
Packit 899799
Packit 899799
name :: [Cu.Cursor] -> [Text]
Packit 899799
name [] = []
Packit 899799
name (c:cs) = ($ name cs) $ case Cu.node c of
Packit 899799
                              Res.NodeElement e -> ((Res.nameLocalName $ Res.elementName e) :)
Packit 899799
                              _ -> id
Packit 899799
Packit 899799
cursor :: Cu.Cursor
Packit 899799
cursor =
Packit 899799
    Cu.fromDocument $ Res.parseLBS_ def input
Packit 899799
  where
Packit 899799
    input = L.concat
Packit 899799
        [ "<foo attr=\"x\">"
Packit 899799
        ,    "<bar1/>"
Packit 899799
        ,    "<bar2>"
Packit 899799
        ,       "<baz1/>"
Packit 899799
        ,       "<baz2 attr=\"y\"/>"
Packit 899799
        ,       "<baz3>a</baz3>"
Packit 899799
        ,    "</bar2>"
Packit 899799
        ,    "<bar3>"
Packit 899799
        ,       "<bin1/>"
Packit 899799
        ,       "b"
Packit 899799
        ,       "<bin2/>"
Packit 899799
        ,       "<bin3/>"
Packit 899799
        ,    "</bar3>"
Packit 899799
        ,    "<Bar1 xmlns=\"http://example.com\" Attr=\"q\"/>"
Packit 899799
        , "</foo>"
Packit 899799
        ]
Packit 899799
Packit 899799
bar2, baz2, bar3, bin2 :: Cu.Cursor
Packit 899799
bar2 = Cu.child cursor !! 1
Packit 899799
baz2 = Cu.child bar2 !! 1
Packit 899799
Packit 899799
bar3 = Cu.child cursor !! 2
Packit 899799
bin2 = Cu.child bar3 !! 1
Packit 899799
Packit 899799
cursorParent, cursorAncestor, cursorOrSelf, cursorPreceding, cursorFollowing,
Packit 899799
    cursorPrecedingSib, cursorFollowingSib, cursorDescendant, cursorCheck,
Packit 899799
    cursorPredicate, cursorCheckNode, cursorCheckElement, cursorCheckName,
Packit 899799
    cursorAnyElement, cursorElement, cursorLaxElement, cursorContent,
Packit 899799
    cursorAttribute, cursorLaxAttribute, cursorHasAttribute,
Packit 899799
    cursorAttributeIs, cursorDeep, cursorForce, cursorForceM,
Packit 899799
    resolvedIdentifies, resolvedAllGood, resolvedMergeContent,
Packit 899799
    testHtmlEntities
Packit 899799
    :: Assertion
Packit 899799
cursorParent = name (Cu.parent bar2) @?= ["foo"]
Packit 899799
cursorAncestor = name (Cu.ancestor baz2) @?= ["bar2", "foo"]
Packit 899799
cursorOrSelf = name (Cu.orSelf Cu.ancestor baz2) @?= ["baz2", "bar2", "foo"]
Packit 899799
cursorPreceding = do
Packit 899799
  name (Cu.preceding baz2) @?= ["baz1", "bar1"]
Packit 899799
  name (Cu.preceding bin2) @?= ["bin1", "baz3", "baz2", "baz1", "bar2", "bar1"]
Packit 899799
cursorFollowing = do
Packit 899799
  name (Cu.following baz2) @?= ["baz3", "bar3", "bin1", "bin2", "bin3", "Bar1"]
Packit 899799
  name (Cu.following bar2) @?= ["bar3", "bin1", "bin2", "bin3", "Bar1"]
Packit 899799
cursorPrecedingSib = name (Cu.precedingSibling baz2) @?= ["baz1"]
Packit 899799
cursorFollowingSib = name (Cu.followingSibling baz2) @?= ["baz3"]
Packit 899799
cursorDescendant = (name $ Cu.descendant cursor) @?= T.words "bar1 bar2 baz1 baz2 baz3 bar3 bin1 bin2 bin3 Bar1"
Packit 899799
cursorCheck = null (cursor $.// Cu.check (const False)) @?= True
Packit 899799
cursorPredicate = (name $ cursor $.// Cu.check Cu.descendant) @?= T.words "foo bar2 baz3 bar3"
Packit 899799
cursorCheckNode = (name $ cursor $// Cu.checkNode f) @?= T.words "bar1 bar2 bar3"
Packit 899799
    where f (Res.NodeElement e) = "bar" `T.isPrefixOf` Res.nameLocalName (Res.elementName e)
Packit 899799
          f _               = False
Packit 899799
cursorCheckElement = (name $ cursor $// Cu.checkElement f) @?= T.words "bar1 bar2 bar3"
Packit 899799
    where f e = "bar" `T.isPrefixOf` Res.nameLocalName (Res.elementName e)
Packit 899799
cursorCheckName = (name $ cursor $// Cu.checkName f) @?= T.words "bar1 bar2 bar3"
Packit 899799
    where f n = "bar" `T.isPrefixOf` nameLocalName n
Packit 899799
cursorAnyElement = (name $ cursor $// Cu.anyElement) @?= T.words "bar1 bar2 baz1 baz2 baz3 bar3 bin1 bin2 bin3 Bar1"
Packit 899799
cursorElement = (name $ cursor $// Cu.element "bar1") @?= ["bar1"]
Packit 899799
cursorLaxElement = (name $ cursor $// Cu.laxElement "bar1") @?= ["bar1", "Bar1"]
Packit 899799
cursorContent = do
Packit 899799
  Cu.content cursor @?= []
Packit 899799
  (cursor $.// Cu.content) @?= ["a", "b"]
Packit 899799
cursorAttribute = Cu.attribute "attr" cursor @?= ["x"]
Packit 899799
cursorLaxAttribute = (cursor $.// Cu.laxAttribute "Attr") @?= ["x", "y", "q"]
Packit 899799
Packit 899799
cursorHasAttribute = (length $ cursor $.// Cu.hasAttribute "attr") @?= 2
Packit 899799
cursorAttributeIs = (length $ cursor $.// Cu.attributeIs "attr" "y") @?= 1
Packit 899799
Packit 899799
cursorDeep = do
Packit 899799
  (Cu.element "foo" &/ Cu.element "bar2" &// Cu.attribute "attr") cursor @?= ["y"]
Packit 899799
  (return &.// Cu.attribute "attr") cursor @?= ["x", "y"]
Packit 899799
  (cursor $.// Cu.attribute "attr") @?= ["x", "y"]
Packit 899799
  (cursor $/ Cu.element "bar2" &// Cu.attribute "attr") @?= ["y"]
Packit 899799
  (cursor $/ Cu.element "bar2" &/ Cu.element "baz2" >=> Cu.attribute "attr") @?= ["y"]
Packit 899799
  null (cursor $| Cu.element "foo") @?= False
Packit 899799
cursorForce = do
Packit 899799
  Cu.force DummyEx [] @?= (Nothing :: Maybe Integer)
Packit 899799
  Cu.force DummyEx [1] @?= Just (1 :: Int)
Packit 899799
  Cu.force DummyEx [1,2] @?= Just (1 :: Int)
Packit 899799
cursorForceM = do
Packit 899799
  Cu.forceM DummyEx [] @?= (Nothing :: Maybe Integer)
Packit 899799
  Cu.forceM DummyEx [Just 1, Nothing] @?= Just (1 :: Int)
Packit 899799
  Cu.forceM DummyEx [Nothing, Just (1 :: Int)] @?= Nothing
Packit 899799
Packit 899799
data DummyEx = DummyEx
Packit 899799
    deriving (Show, Typeable)
Packit 899799
instance Exception DummyEx
Packit 899799
Packit 899799
showEq :: (Show a, Show b) => Either a b -> Either a b -> Assertion
Packit 899799
showEq x y = show x @=? show y
Packit 899799
Packit 899799
resolvedIdentifies =
Packit 899799
    Left (toException $ Res.UnresolvedEntityException $ Set.fromList ["foo", "bar", "baz"]) `showEq`
Packit 899799
    Res.parseLBS def
Packit 899799
    "<root attr='&bar;'>&foo; --- &baz; &foo;</root>"
Packit 899799
Packit 899799
testHtmlEntities =
Packit 899799
    Res.parseLBS_ def
Packit 899799
        { P.psDecodeEntities = P.decodeHtmlEntities
Packit 899799
        } xml1 @=? Res.parseLBS_ def xml2
Packit 899799
  where
Packit 899799
    xml1 = "<root> </root>"
Packit 899799
    xml2 = "<root> </root>"
Packit 899799
Packit 899799
resolvedAllGood =
Packit 899799
    D.parseLBS_ def xml @=?
Packit 899799
    Res.toXMLDocument (Res.parseLBS_ def xml)
Packit 899799
  where
Packit 899799
    xml = "<foo><bar/><baz/></foo>"
Packit 899799
Packit 899799
resolvedMergeContent =
Packit 899799
    Res.documentRoot (Res.parseLBS_ def xml) @=?
Packit 899799
    Res.Element "foo" Map.empty [Res.NodeContent "bar&baz"]
Packit 899799
  where
Packit 899799
    xml = "<foo>bar&baz</foo>"
Packit 899799
Packit 899799
parseIgnoreBOM :: Assertion
Packit 899799
parseIgnoreBOM = do
Packit 899799
    either (const $ Left (1 :: Int)) Right (Res.parseText Res.def "\xfeef<foo/>") @?=
Packit 899799
        either (const $ Left (2 :: Int)) Right (Res.parseText Res.def "<foo/>")
Packit 899799
Packit 899799
stripDuplicateAttributes :: Assertion
Packit 899799
stripDuplicateAttributes = do
Packit 899799
    "<foo bar=\"baz\"/>" @=?
Packit 899799
        D.renderLBS def (Document (Prologue [] Nothing []) (Element "foo" [("bar", [ContentText "baz"]), ("bar", [ContentText "bin"])] []) [])
Packit 899799
    "<foo x:bar=\"baz\" xmlns:x=\"namespace\"/>" @=?
Packit 899799
        D.renderLBS def (Document (Prologue [] Nothing []) (Element "foo"
Packit 899799
            [ ("x:bar", [ContentText "baz"])
Packit 899799
            , (Name "bar" (Just "namespace") (Just "x"), [ContentText "bin"])
Packit 899799
            ] []) [])
Packit 899799
Packit 899799
testRenderComments :: Assertion
Packit 899799
testRenderComments =do
Packit 899799
    "<foo></foo>"
Packit 899799
        @=? D.renderLBS def (Document (Prologue [] Nothing [])
Packit 899799
            (Element "foo" [] [NodeComment "comment"]) [])
Packit 899799
Packit 899799
resolvedInline :: Assertion
Packit 899799
resolvedInline = do
Packit 899799
    Res.Document _ root _ <- return $ Res.parseLBS_ Res.def "]><foo>&bar;</foo>"
Packit 899799
    root @?= Res.Element "foo" Map.empty [Res.NodeContent "baz"]
Packit 899799
    Res.Document _ root2 _ <- return $ Res.parseLBS_ Res.def "]><foo bar='&bar;'/>"
Packit 899799
    root2 @?= Res.Element "foo" (Map.singleton "bar" "baz") []
Packit 899799
Packit 899799
casePretty :: Assertion
Packit 899799
casePretty = do
Packit 899799
    let pretty = S.unlines
Packit 899799
            [ ""
Packit 899799
            , ""
Packit 899799
            , "<foo bar=\"bar\" baz=\"baz\">"
Packit 899799
            , "    
Packit 899799
            , "      bar=\"bar\""
Packit 899799
            , "      baz=\"baz\""
Packit 899799
            , "      bin=\"bin\">"
Packit 899799
            , "        Hello World"
Packit 899799
            , "    </foo>"
Packit 899799
            , "    <foo/>"
Packit 899799
            , "    "
Packit 899799
            , "    "
Packit 899799
            , "    <bar>"
Packit 899799
            , "        bar content"
Packit 899799
            , "    </bar>"
Packit 899799
            , "</foo>"
Packit 899799
            ]
Packit 899799
        doctype = Res.Doctype "foo" Nothing
Packit 899799
        doc = Res.Document (Res.Prologue [] (Just doctype) []) root []
Packit 899799
        root = Res.Element "foo" (Map.fromList [("bar", "bar"), ("baz", "baz")])
Packit 899799
                [ Res.NodeElement $ Res.Element "foo" (Map.fromList [("bar", "bar"), ("baz", "baz"), ("bin", "bin")])
Packit 899799
                    [ Res.NodeContent "  Hello World\n\n"
Packit 899799
                    , Res.NodeContent "  "
Packit 899799
                    ]
Packit 899799
                , Res.NodeElement $ Res.Element "foo" Map.empty []
Packit 899799
                , Res.NodeInstruction $ Res.Instruction "foo" "bar"
Packit 899799
                , Res.NodeComment "foo bar\n\r\nbaz    \tbin "
Packit 899799
                , Res.NodeElement $ Res.Element "bar" Map.empty [Res.NodeContent "bar content"]
Packit 899799
                ]
Packit 899799
    pretty @=? S.concat (L.toChunks $ Res.renderLBS def { D.rsPretty = True } doc)
Packit 899799
Packit 899799
caseTopLevelNamespace :: Assertion
Packit 899799
caseTopLevelNamespace = do
Packit 899799
    let lbs = S.concat
Packit 899799
            [ ""
Packit 899799
            , "<foo xmlns:bar=\"baz\">"
Packit 899799
            , "<subfoo bar:bin=\"\"/>"
Packit 899799
            , "</foo>"
Packit 899799
            ]
Packit 899799
        rs = def { D.rsNamespaces = [("bar", "baz")] }
Packit 899799
        doc = Res.Document (Res.Prologue [] Nothing [])
Packit 899799
                (Res.Element "foo" Map.empty
Packit 899799
                    [ Res.NodeElement
Packit 899799
                        $ Res.Element "subfoo" (Map.singleton "{baz}bin" "") []
Packit 899799
                    ])
Packit 899799
                []
Packit 899799
    lbs @=? S.concat (L.toChunks $ Res.renderLBS rs doc)
Packit 899799
Packit 899799
caseTopLevelNamespacePrefix :: Assertion
Packit 899799
caseTopLevelNamespacePrefix = do
Packit 899799
    let lbs = S.concat
Packit 899799
            [ ""
Packit 899799
            , "<foo xmlns:bar=\"baz\">"
Packit 899799
            , "<subfoo bar:bin=\"\"/>"
Packit 899799
            , "</foo>"
Packit 899799
            ]
Packit 899799
        rs = def { D.rsNamespaces = [("bar", "baz")] }
Packit 899799
        doc = Res.Document (Res.Prologue [] Nothing [])
Packit 899799
                (Res.Element "foo" Map.empty
Packit 899799
                    [ Res.NodeElement
Packit 899799
                        $ Res.Element "subfoo" (Map.fromList [(Name "bin" (Just "baz") (Just "bar"), "")]) []
Packit 899799
                    ])
Packit 899799
                []
Packit 899799
    lbs @=? S.concat (L.toChunks $ Res.renderLBS rs doc)
Packit 899799
Packit 899799
caseTLNConflict :: Assertion
Packit 899799
caseTLNConflict = do
Packit 899799
    let lbs = S.concat
Packit 899799
            [ ""
Packit 899799
            , "<foo xmlns:bar=\"something\" bar:x=\"y\">"
Packit 899799
            , "<subfoo xmlns:bar_=\"baz\" bar_:bin=\"\"/>"
Packit 899799
            , "</foo>"
Packit 899799
            ]
Packit 899799
        rs = def { D.rsNamespaces = [("bar", "baz")] }
Packit 899799
        doc = Res.Document (Res.Prologue [] Nothing [])
Packit 899799
                (Res.Element "foo" (Map.fromList [(Name "x" (Just "something") (Just "bar"), "y")])
Packit 899799
                    [ Res.NodeElement
Packit 899799
                        $ Res.Element "subfoo" (Map.fromList [(Name "bin" (Just "baz") (Just "bar"), "")]) []
Packit 899799
                    ])
Packit 899799
                []
Packit 899799
    lbs @=? S.concat (L.toChunks $ Res.renderLBS rs doc)
Packit 899799
Packit 899799
caseBlazeHtml :: Assertion
Packit 899799
caseBlazeHtml =
Packit 899799
    expected @=? str
Packit 899799
  where
Packit 899799
    str = renderMarkup $ toMarkup $ Res.Document (Res.Prologue [] Nothing []) root []
Packit 899799
    root :: Res.Element
Packit 899799
    root = Res.Element "html" Map.empty
Packit 899799
        [ Res.NodeElement $ Res.Element "head" Map.empty
Packit 899799
            [ Res.NodeElement $ Res.Element "title" Map.empty [Res.NodeContent "Test"]
Packit 899799
            , Res.NodeElement $ Res.Element "script" Map.empty
Packit 899799
                [Res.NodeContent "if (5 < 6 || 8 > 9) alert('Hello World!');"]
Packit 899799
            , Res.NodeElement $ Res.Element "{http://www.snoyman.com/xml2html}ie-cond" (Map.singleton "cond" "lt IE 7")
Packit 899799
                [Res.NodeElement $ Res.Element "link" (Map.singleton "href" "ie6.css") []]
Packit 899799
            , Res.NodeElement $ Res.Element "style" Map.empty
Packit 899799
                [Res.NodeContent "body > h1 { color: red }"]
Packit 899799
            ]
Packit 899799
        , Res.NodeElement $ Res.Element "body" Map.empty
Packit 899799
            [ Res.NodeElement $ Res.Element "h1" Map.empty [Res.NodeContent "Hello World!"]
Packit 899799
            ]
Packit 899799
        ]
Packit 899799
    expected :: String
Packit 899799
    expected = concat
Packit 899799
        [ "\n"
Packit 899799
        , "<html><head><title>Test</title><script>if (5 < 6 || 8 > 9) alert('Hello World!');</script>"
Packit 899799
        , ""
Packit 899799
        , "<style>body > h1 { color: red }</style>"
Packit 899799
        , "</head>"
Packit 899799
        , "<body>

Hello World!

</body></html>"
Packit 899799
        ]
Packit 899799
Packit 899799
caseAttrReorder :: Assertion
Packit 899799
caseAttrReorder = do
Packit 899799
    let lbs = S.concat
Packit 899799
            [ ""
Packit 899799
            , "<foo c=\"c\" b=\"b\" a=\"a\">"
Packit 899799
            , "<bar a=\"a\" b=\"b\" c=\"c\"/>"
Packit 899799
            , "</foo>"
Packit 899799
            ]
Packit 899799
        rs = def { Res.rsAttrOrder = \name m ->
Packit 899799
                        case name of
Packit 899799
                            "foo" -> reverse $ Map.toAscList m
Packit 899799
                            _     -> Map.toAscList m
Packit 899799
                 }
Packit 899799
        attrs = Map.fromList [("a", "a"), ("b", "b"), ("c", "c")]
Packit 899799
        doc = Res.Document (Res.Prologue [] Nothing [])
Packit 899799
                (Res.Element "foo" attrs
Packit 899799
                    [ Res.NodeElement
Packit 899799
                        $ Res.Element "bar" attrs []
Packit 899799
                    ])
Packit 899799
                []
Packit 899799
    lbs @=? S.concat (L.toChunks $ Res.renderLBS rs doc)
Packit 899799
Packit 899799
caseOrderAttrs :: Assertion
Packit 899799
caseOrderAttrs = do
Packit 899799
    let lbs = S.concat
Packit 899799
            [ ""
Packit 899799
            , "<foo c=\"c\" b=\"b\" a=\"a\">"
Packit 899799
            , "<bar a=\"a\" b=\"b\" c=\"c\"/>"
Packit 899799
            , "</foo>"
Packit 899799
            ]
Packit 899799
        rs = def { Res.rsAttrOrder = Res.orderAttrs
Packit 899799
                     [("foo", ["c", "b"])]
Packit 899799
                 }
Packit 899799
        attrs = Map.fromList [("a", "a"), ("b", "b"), ("c", "c")]
Packit 899799
        doc = Res.Document (Res.Prologue [] Nothing [])
Packit 899799
                (Res.Element "foo" attrs
Packit 899799
                    [ Res.NodeElement
Packit 899799
                        $ Res.Element "bar" attrs []
Packit 899799
                    ])
Packit 899799
                []
Packit 899799
    lbs @=? S.concat (L.toChunks $ Res.renderLBS rs doc)
Packit 899799
Packit 899799
caseParseCdata :: Assertion
Packit 899799
caseParseCdata = do
Packit 899799
    let lbs = ""
Packit 899799
        doc = Res.Document (Res.Prologue [] Nothing [])
Packit 899799
                (Res.Element "a" Map.empty
Packit 899799
                    [ Res.NodeContent "www.google.com"
Packit 899799
                    ])
Packit 899799
                []
Packit 899799
    Res.parseLBS_ def lbs @?= doc
Packit 899799
Packit 899799
caseRetainNamespaces :: Assertion
Packit 899799
caseRetainNamespaces = do
Packit 899799
    let lbs = "<foo xmlns:bar='baz'><bar:bin/><bin3 xmlns='bin4'></bin3></foo>"
Packit 899799
        doc = Res.parseLBS_ def { Res.psRetainNamespaces = True } lbs
Packit 899799
    doc `shouldBe` Res.Document
Packit 899799
        (Res.Prologue [] Nothing [])
Packit 899799
        (Res.Element
Packit 899799
            "foo"
Packit 899799
            (Map.singleton "xmlns:bar" "baz")
Packit 899799
            [ Res.NodeElement $ Res.Element
Packit 899799
                "{baz}bin"
Packit 899799
                Map.empty
Packit 899799
                []
Packit 899799
            , Res.NodeElement $ Res.Element
Packit 899799
                "{bin4}bin3"
Packit 899799
                (Map.singleton "xmlns" "bin4")
Packit 899799
                []
Packit 899799
            ])
Packit 899799
        []
Packit 899799
Packit 899799
caseIso8859_1 :: Assertion
Packit 899799
caseIso8859_1 = do
Packit 899799
    let lbs = "<foo>\232</foo>"
Packit 899799
        doc = Res.parseLBS_ def lbs
Packit 899799
    doc `shouldBe` Res.Document
Packit 899799
        (Res.Prologue [] Nothing [])
Packit 899799
        (Res.Element
Packit 899799
            "foo"
Packit 899799
            Map.empty
Packit 899799
            [Res.NodeContent "\232"])
Packit 899799
        []
Packit 899799
Packit 899799
caseRenderCDATA :: Assertion
Packit 899799
caseRenderCDATA = do
Packit 899799
    let doc = Res.Document (Res.Prologue [] Nothing [])
Packit 899799
                (Res.Element "a" Map.empty
Packit 899799
                    [ Res.NodeContent "www.google.com"
Packit 899799
                    ])
Packit 899799
                []
Packit 899799
        withoutCDATA = Res.renderLBS def doc
Packit 899799
        withCDATA = Res.renderLBS (def { Res.rsUseCDATA = const True }) doc
Packit 899799
    withCDATA `shouldBe` ""
Packit 899799
    withoutCDATA `shouldBe` "www.google.com"
Packit 899799
Packit 899799
caseEscapesCDATA :: Assertion
Packit 899799
caseEscapesCDATA = do
Packit 899799
    let doc = Res.Document (Res.Prologue [] Nothing [])
Packit 899799
                (Res.Element "a" Map.empty
Packit 899799
                    [ Res.NodeContent "]]>"
Packit 899799
                    ])
Packit 899799
                []
Packit 899799
        result = Res.renderLBS (def { Res.rsUseCDATA = const True }) doc
Packit 899799
    result `shouldBe` "]]>"