1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
{-# LANGUAGE OverloadedStrings #-}
{- |
Module : Tests.Readers.HTML
Copyright : © 2006-2023 John MacFarlane
License : GNU GPL, version 2 or above
Maintainer : John MacFarlane <jgm@berkeley.edu>
Stability : alpha
Portability : portable
Tests for the HTML reader.
-}
module Tests.Readers.HTML (tests) where
import Data.Text (Text)
import qualified Data.Text as T
import Test.Tasty
import Test.Tasty.QuickCheck
import Test.Tasty.Options (IsOption(defaultValue))
import Tests.Helpers
import Text.Pandoc
import Text.Pandoc.Shared (isHeaderBlock)
import Text.Pandoc.Arbitrary ()
import Text.Pandoc.Builder
import Text.Pandoc.Walk (walk)
html :: Text -> Pandoc
html = purely $ readHtml def
htmlNativeDivs :: Text -> Pandoc
htmlNativeDivs = purely $ readHtml def { readerExtensions = enableExtension Ext_native_divs $ readerExtensions def }
makeRoundTrip :: Block -> Block
makeRoundTrip CodeBlock{} = Para [Str "code block was here"]
makeRoundTrip LineBlock{} = Para [Str "line block was here"]
makeRoundTrip RawBlock{} = Para [Str "raw block was here"]
makeRoundTrip (Div attr bs) = Div attr $ filter (not . isHeaderBlock) bs
-- avoids round-trip failures related to makeSections
-- e.g. with [Div ("loc",[],[("a","11"),("b_2","a b c")]) [Header 3 ("",[],[]) []]]
makeRoundTrip Table{} = Para [Str "table block was here"]
makeRoundTrip x = x
removeRawInlines :: Inline -> Inline
removeRawInlines RawInline{} = Str "raw inline was here"
removeRawInlines x = x
roundTrip :: Blocks -> Bool
roundTrip b = d'' == d'''
where d = walk removeRawInlines $
walk makeRoundTrip $ Pandoc nullMeta $ toList b
d' = rewrite d
d'' = rewrite d'
d''' = rewrite d''
rewrite = html . (`T.snoc` '\n') .
purely (writeHtml5String def
{ writerWrapText = WrapPreserve })
tests :: [TestTree]
tests = [ testGroup "base tag"
[ test html "simple" $
"<head><base href=\"http://www.w3schools.com/images/foo\" ></head><body><img src=\"stickman.gif\" alt=\"Stickman\"></head>" =?>
plain (image "http://www.w3schools.com/images/stickman.gif" "" (text "Stickman"))
, test html "slash at end of base" $
"<head><base href=\"http://www.w3schools.com/images/\" ></head><body><img src=\"stickman.gif\" alt=\"Stickman\"></head>" =?>
plain (image "http://www.w3schools.com/images/stickman.gif" "" (text "Stickman"))
, test html "slash at beginning of href" $
"<head><base href=\"http://www.w3schools.com/images/\" ></head><body><img src=\"/stickman.gif\" alt=\"Stickman\"></head>" =?>
plain (image "http://www.w3schools.com/stickman.gif" "" (text "Stickman"))
, test html "absolute URL" $
"<head><base href=\"http://www.w3schools.com/images/\" ></head><body><img src=\"http://example.com/stickman.gif\" alt=\"Stickman\"></head>" =?>
plain (image "http://example.com/stickman.gif" "" (text "Stickman"))
]
, testGroup "anchors"
[ test html "anchor without href" $ "<a name=\"anchor\"/>" =?>
plain (spanWith ("anchor",[],[]) mempty)
]
, testGroup "img"
[ test html "data-external attribute" $ "<img data-external=\"1\" src=\"http://example.com/stickman.gif\">" =?>
plain (imageWith ("", [], [("external", "1")]) "http://example.com/stickman.gif" "" "")
, test html "title" $ "<img title=\"The title\" src=\"http://example.com/stickman.gif\">" =?>
plain (imageWith ("", [], []) "http://example.com/stickman.gif" "The title" "")
]
, testGroup "lang"
[ test html "lang on <html>" $ "<html lang=\"es\">hola" =?>
setMeta "lang" (text "es") (doc (plain (text "hola")))
, test html "xml:lang on <html>" $ "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"es\"><head></head><body>hola</body></html>" =?>
setMeta "lang" (text "es") (doc (plain (text "hola")))
]
, testGroup "main"
[ test htmlNativeDivs "<main> becomes <div role=main>" $ "<main>hello</main>" =?>
doc (divWith ("", [], [("role", "main")]) (plain (text "hello")))
, test htmlNativeDivs "<main role=X> becomes <div role=X>" $ "<main role=foobar>hello</main>" =?>
doc (divWith ("", [], [("role", "foobar")]) (plain (text "hello")))
, test htmlNativeDivs "<main> has attributes preserved" $ "<main id=foo class=bar data-baz=qux>hello</main>" =?>
doc (divWith ("foo", ["bar"], [("role", "main"), ("baz", "qux")]) (plain (text "hello")))
, test htmlNativeDivs "<main> closes <p>" $ "<p>hello<main>main content</main>" =?>
doc (para (text "hello") <> divWith ("", [], [("role", "main")]) (plain (text "main content")))
, test htmlNativeDivs "<main> followed by text" $ "<main>main content</main>non-main content" =?>
doc (divWith ("", [], [("role", "main")]) (plain (text "main content")) <> plain (text "non-main content"))
]
, testGroup "code"
[
test html "inline code block" $
"<code>Answer is 42</code>" =?>
plain (codeWith ("",[],[]) "Answer is 42")
]
, testGroup "tt"
[
test html "inline tt block" $
"<tt>Answer is 42</tt>" =?>
plain (codeWith ("",[],[]) "Answer is 42")
]
, testGroup "samp"
[
test html "inline samp block" $
"<samp>Answer is 42</samp>" =?>
plain (codeWith ("",["sample"],[]) "Answer is 42")
]
, testGroup "var"
[ test html "inline var block" $
"<var>result</var>" =?>
plain (codeWith ("",["variable"],[]) "result")
]
, testGroup "header"
[ test htmlNativeDivs "<header> is parsed as a div" $
"<header id=\"title\">Title</header>" =?>
divWith ("title", mempty, mempty) (plain "Title")
]
, testGroup "code block"
[ test html "attributes in pre > code element" $
"<pre><code id=\"a\" class=\"python\">\nprint('hi')\n</code></pre>"
=?>
codeBlockWith ("a", ["python"], []) "print('hi')"
, test html "attributes in pre take precedence" $
"<pre id=\"c\"><code id=\"d\">\nprint('hi mom!')\n</code></pre>"
=?>
codeBlockWith ("c", [], []) "print('hi mom!')"
]
, askOption $ \(QuickCheckTests numtests) ->
testProperty "Round trip" $
withMaxSuccess (if QuickCheckTests numtests == defaultValue
then 25
else numtests) roundTrip
]
|