2015-05-14 05:39:01 +02:00
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
2019-02-04 22:52:31 +01:00
|
|
|
{- |
|
|
|
|
Module : Tests.Readers.HTML
|
2022-01-01 20:02:31 +01:00
|
|
|
Copyright : © 2006-2022 John MacFarlane
|
2019-02-04 22:52:31 +01:00
|
|
|
License : GNU GPL, version 2 or above
|
|
|
|
|
|
|
|
Maintainer : John MacFarlane <jgm@berkeley.edu>
|
|
|
|
Stability : alpha
|
|
|
|
Portability : portable
|
|
|
|
|
|
|
|
Tests for the HTML reader.
|
|
|
|
-}
|
2015-05-14 05:39:01 +02:00
|
|
|
module Tests.Readers.HTML (tests) where
|
|
|
|
|
2017-10-28 05:28:29 +02:00
|
|
|
import Data.Text (Text)
|
2018-09-10 11:15:27 +02:00
|
|
|
import qualified Data.Text as T
|
2017-03-14 17:05:36 +01:00
|
|
|
import Test.Tasty
|
2018-09-10 11:15:27 +02:00
|
|
|
import Test.Tasty.QuickCheck
|
2018-10-16 07:15:43 +02:00
|
|
|
import Test.Tasty.Options (IsOption(defaultValue))
|
2015-05-14 05:39:01 +02:00
|
|
|
import Tests.Helpers
|
|
|
|
import Text.Pandoc
|
2020-11-24 15:42:19 +01:00
|
|
|
import Text.Pandoc.Shared (isHeaderBlock)
|
2017-03-04 13:03:41 +01:00
|
|
|
import Text.Pandoc.Arbitrary ()
|
|
|
|
import Text.Pandoc.Builder
|
2018-09-10 11:15:27 +02:00
|
|
|
import Text.Pandoc.Walk (walk)
|
2015-05-14 05:39:01 +02:00
|
|
|
|
2017-06-10 18:26:44 +02:00
|
|
|
html :: Text -> Pandoc
|
2016-12-01 18:47:05 +01:00
|
|
|
html = purely $ readHtml def
|
2015-05-14 05:39:01 +02:00
|
|
|
|
2017-08-09 18:10:12 +02:00
|
|
|
htmlNativeDivs :: Text -> Pandoc
|
|
|
|
htmlNativeDivs = purely $ readHtml def { readerExtensions = enableExtension Ext_native_divs $ readerExtensions def }
|
|
|
|
|
2018-09-10 11:15:27 +02:00
|
|
|
makeRoundTrip :: Block -> Block
|
|
|
|
makeRoundTrip CodeBlock{} = Para [Str "code block was here"]
|
|
|
|
makeRoundTrip LineBlock{} = Para [Str "line block was here"]
|
2018-09-10 13:28:28 +02:00
|
|
|
makeRoundTrip RawBlock{} = Para [Str "raw block was here"]
|
2019-12-21 21:15:35 +01:00
|
|
|
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 ("",[],[]) []]]
|
2020-11-24 15:42:19 +01:00
|
|
|
makeRoundTrip Table{} = Para [Str "table block was here"]
|
2018-09-10 11:15:27 +02:00
|
|
|
makeRoundTrip x = x
|
|
|
|
|
|
|
|
removeRawInlines :: Inline -> Inline
|
|
|
|
removeRawInlines RawInline{} = Str "raw inline was here"
|
|
|
|
removeRawInlines x = x
|
|
|
|
|
2018-09-11 18:23:46 +02:00
|
|
|
roundTrip :: Blocks -> Bool
|
2018-09-10 11:15:27 +02:00
|
|
|
roundTrip b = d'' == d'''
|
2018-09-27 18:45:46 +02:00
|
|
|
where d = walk removeRawInlines $
|
|
|
|
walk makeRoundTrip $ Pandoc nullMeta $ toList b
|
2018-09-10 11:15:27 +02:00
|
|
|
d' = rewrite d
|
|
|
|
d'' = rewrite d'
|
|
|
|
d''' = rewrite d''
|
2020-11-24 15:42:19 +01:00
|
|
|
rewrite = html . (`T.snoc` '\n') .
|
2018-09-27 18:45:46 +02:00
|
|
|
purely (writeHtml5String def
|
|
|
|
{ writerWrapText = WrapPreserve })
|
2018-09-10 11:15:27 +02:00
|
|
|
|
2017-03-14 17:05:36 +01:00
|
|
|
tests :: [TestTree]
|
2015-05-14 05:39:01 +02:00
|
|
|
tests = [ testGroup "base tag"
|
|
|
|
[ test html "simple" $
|
2016-03-11 04:59:55 +01:00
|
|
|
"<head><base href=\"http://www.w3schools.com/images/foo\" ></head><body><img src=\"stickman.gif\" alt=\"Stickman\"></head>" =?>
|
2015-05-14 05:39:01 +02:00
|
|
|
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"))
|
2016-03-11 04:59:55 +01:00
|
|
|
, 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"))
|
2015-05-14 05:39:01 +02:00
|
|
|
, 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"))
|
|
|
|
]
|
2016-11-13 22:41:11 +01:00
|
|
|
, testGroup "anchors"
|
|
|
|
[ test html "anchor without href" $ "<a name=\"anchor\"/>" =?>
|
|
|
|
plain (spanWith ("anchor",[],[]) mempty)
|
|
|
|
]
|
2021-07-07 01:06:29 +02:00
|
|
|
, 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" "")
|
|
|
|
]
|
2017-06-27 10:19:37 +02:00
|
|
|
, 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")))
|
|
|
|
]
|
2017-08-09 18:10:12 +02:00
|
|
|
, 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>" =?>
|
2019-03-25 16:43:59 +01:00
|
|
|
doc (divWith ("foo", ["bar"], [("role", "main"), ("baz", "qux")]) (plain (text "hello")))
|
2017-08-09 18:10:12 +02:00
|
|
|
, 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"))
|
|
|
|
]
|
2019-10-23 17:44:24 +02:00
|
|
|
, testGroup "samp"
|
|
|
|
[
|
2020-02-07 17:32:47 +01:00
|
|
|
test html "inline samp block" $
|
|
|
|
"<samp>Answer is 42</samp>" =?>
|
2019-10-23 17:44:24 +02:00
|
|
|
plain (codeWith ("",["sample"],[]) "Answer is 42")
|
|
|
|
]
|
2019-11-04 17:42:30 +01:00
|
|
|
, testGroup "var"
|
2021-05-15 16:36:13 +02:00
|
|
|
[ 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")
|
|
|
|
]
|
2021-05-17 18:08:02 +02:00
|
|
|
, 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 precendence" $
|
|
|
|
"<pre id=\"c\"><code id=\"d\">\nprint('hi mom!')\n</code></pre>"
|
|
|
|
=?>
|
|
|
|
codeBlockWith ("c", [], []) "print('hi mom!')"
|
|
|
|
]
|
2018-10-16 07:15:43 +02:00
|
|
|
, askOption $ \(QuickCheckTests numtests) ->
|
|
|
|
testProperty "Round trip" $
|
|
|
|
withMaxSuccess (if QuickCheckTests numtests == defaultValue
|
|
|
|
then 25
|
|
|
|
else numtests) roundTrip
|
2015-05-14 05:39:01 +02:00
|
|
|
]
|