2017-03-04 13:03:41 +01:00
{- # LANGUAGE OverloadedStrings # -}
{- # LANGUAGE ScopedTypeVariables # -}
2019-02-04 22:52:31 +01:00
{- |
Module : Tests . Readers . RST
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 RST reader .
- }
2011-01-26 18:10:39 +01:00
module Tests.Readers.RST ( tests ) where
2017-06-10 18:26:44 +02:00
import Data.Text ( Text )
import qualified Data.Text as T
2017-03-14 17:05:36 +01:00
import Test.Tasty
2022-02-23 09:19:36 +01:00
import Test.Tasty.HUnit ( HasCallStack )
2011-01-26 18:10:39 +01:00
import Tests.Helpers
import Text.Pandoc
2017-03-04 13:03:41 +01:00
import Text.Pandoc.Arbitrary ( )
import Text.Pandoc.Builder
2011-01-26 18:10:39 +01:00
2017-06-10 18:26:44 +02:00
rst :: Text -> Pandoc
2016-12-01 18:47:05 +01:00
rst = purely $ readRST def { readerStandalone = True }
2011-01-26 18:10:39 +01:00
2012-02-05 22:23:06 +01:00
infix 4 =:
2022-02-23 09:19:36 +01:00
( =: ) :: ( ToString c , HasCallStack )
2017-06-10 18:26:44 +02:00
=> String -> ( Text , c ) -> TestTree
2011-01-26 18:10:39 +01:00
( =: ) = test rst
2017-03-14 17:05:36 +01:00
tests :: [ TestTree ]
2011-04-11 23:45:42 +02:00
tests = [ " line block with blank line " =:
2016-10-13 08:46:44 +02:00
" | a \ n | \ n | b " =?> lineBlock [ " a " , mempty , " \ 160 b " ]
2015-07-03 16:40:59 +02:00
, testGroup " field list "
2017-06-10 18:26:44 +02:00
[ " general " =: T . unlines
2013-05-11 07:53:35 +02:00
[ " para "
, " "
, " :Hostname: media08 "
2013-01-23 17:47:43 +01:00
, " :IP address: 10.0.0.19 "
, " :Size: 3ru "
, " :Version: 1 "
, " :Indentation: Since the field marker may be quite long, the second "
, " and subsequent lines of the field body do not have to line up "
, " with the first line, but they must be indented relative to the "
, " field name marker, and they must line up with each other. "
, " :Parameter i: integer "
, " :Final: item "
, " on two lines " ]
2018-01-20 06:25:24 +01:00
=?>
doc ( para " para " <>
2015-07-03 16:40:59 +02:00
definitionList [ ( str " Hostname " , [ para " media08 " ] )
, ( text " IP address " , [ para " 10.0.0.19 " ] )
, ( str " Size " , [ para " 3ru " ] )
, ( str " Version " , [ para " 1 " ] )
2015-12-12 21:21:36 +01:00
, ( str " Indentation " , [ para " Since the field marker may be quite long, the second \ n and subsequent lines of the field body do not have to line up \ n with the first line, but they must be indented relative to the \ n field name marker, and they must line up with each other. " ] )
2015-07-03 16:40:59 +02:00
, ( text " Parameter i " , [ para " integer " ] )
2015-12-12 21:21:36 +01:00
, ( str " Final " , [ para " item \ n on two lines " ] )
2015-07-03 16:40:59 +02:00
] )
2017-06-10 18:26:44 +02:00
, " metadata " =: T . unlines
2013-05-11 07:53:35 +02:00
[ " ===== "
, " Title "
, " ===== "
, " -------- "
, " Subtitle "
, " -------- "
, " "
, " :Version: 1 "
]
2018-01-20 06:25:24 +01:00
=?>
setMeta " version " ( para " 1 " ) ( setMeta " title " ( " Title " :: Inlines )
2015-07-03 16:40:59 +02:00
$ setMeta " subtitle " ( " Subtitle " :: Inlines )
2018-01-20 06:25:24 +01:00
$ doc mempty )
2017-06-10 18:26:44 +02:00
, " with inline markup " =: T . unlines
2015-07-03 16:56:25 +02:00
[ " :*Date*: today "
, " "
, " .. "
2015-07-02 19:16:30 +02:00
, " "
, " :*one*: emphasis "
, " :two_: reference "
, " :`three`_: another one "
, " :``four``: literal "
, " "
, " .. _two: http://example.com "
, " .. _three: http://example.org "
]
2018-01-20 06:25:24 +01:00
=?>
setMeta " date " ( str " today " ) ( doc
2015-07-03 16:56:25 +02:00
$ definitionList [ ( emph " one " , [ para " emphasis " ] )
2015-07-03 16:40:59 +02:00
, ( link " http://example.com " " " " two " , [ para " reference " ] )
, ( link " http://example.org " " " " three " , [ para " another one " ] )
, ( code " four " , [ para " literal " ] )
] )
]
2011-03-18 19:27:42 +01:00
, " URLs with following punctuation " =:
2017-06-10 18:26:44 +02:00
( " http://google.com, http://yahoo.com; http://foo.bar.baz. \ n " <>
2011-03-18 19:27:42 +01:00
" http://foo.bar/baz_(bam) (http://foo.bar) " ) =?>
2011-12-13 23:29:07 +01:00
para ( link " http://google.com " " " " http://google.com " <> " , " <>
link " http://yahoo.com " " " " http://yahoo.com " <> " ; " <>
link " http://foo.bar.baz " " " " http://foo.bar.baz " <> " . " <>
2015-12-12 21:21:36 +01:00
softbreak <>
2011-03-18 19:27:42 +01:00
link " http://foo.bar/baz_(bam) " " " " http://foo.bar/baz_(bam) "
2011-12-13 23:29:07 +01:00
<> " ( " <> link " http://foo.bar " " " " http://foo.bar " <> " ) " )
2015-06-29 18:32:46 +02:00
, " Reference names with special characters " =:
2017-06-10 18:26:44 +02:00
( " A-1-B_2_C:3:D+4+E.5.F_ \ n \ n " <>
2015-07-10 19:35:58 +02:00
" .. _A-1-B_2_C:3:D+4+E.5.F: https://example.com \ n " ) =?>
para ( link " https://example.com " " " " A-1-B_2_C:3:D+4+E.5.F " )
2017-06-10 18:26:44 +02:00
, " Code directive with class and number-lines " =: T . unlines
2016-05-02 05:23:33 +02:00
[ " .. code::python "
, " :number-lines: 34 "
, " :class: class1 class2 class3 "
, " "
, " def func(x): "
, " return y "
] =?>
2018-01-20 06:25:24 +01:00
doc ( codeBlockWith
2016-05-02 05:32:26 +02:00
( " "
2019-01-08 20:36:33 +01:00
, [ " python " , " numberLines " , " class1 " , " class2 " , " class3 " ]
2016-05-02 05:32:26 +02:00
, [ ( " startFrom " , " 34 " ) ]
)
2018-01-20 06:25:24 +01:00
" def func(x): \ n return y " )
2017-06-10 18:26:44 +02:00
, " Code directive with number-lines, no line specified " =: T . unlines
2016-05-02 05:36:19 +02:00
[ " .. code::python "
2019-01-10 07:19:26 +01:00
, " :number-lines: "
2016-05-02 05:36:19 +02:00
, " "
, " def func(x): "
, " return y "
] =?>
2018-01-20 06:25:24 +01:00
doc ( codeBlockWith
2016-05-02 05:36:19 +02:00
( " "
2019-01-08 20:36:33 +01:00
, [ " python " , " numberLines " ]
2019-01-10 07:19:26 +01:00
, []
2016-05-02 05:36:19 +02:00
)
2018-01-20 06:25:24 +01:00
" def func(x): \ n return y " )
2014-12-11 18:14:03 +01:00
, testGroup " literal / line / code blocks "
2017-06-10 18:26:44 +02:00
[ " indented literal block " =: T . unlines
2014-12-11 18:14:03 +01:00
[ " :: "
, " "
, " block quotes "
, " "
, " can go on for many lines "
, " but must stop here " ]
2018-01-20 06:25:24 +01:00
=?>
doc (
2014-12-11 18:14:03 +01:00
codeBlock " block quotes \ n \ n can go on for many lines " <>
para " but must stop here " )
, " line block with 3 lines " =: " | a \ n | b \ n | c "
2016-10-13 08:46:44 +02:00
=?> lineBlock [ " a " , " b " , " c " ]
2017-08-28 16:48:46 +02:00
, " line blocks with blank lines " =: T . unlines
[ " | "
, " "
, " | "
, " | a "
, " | b "
, " | "
, " "
, " | "
] =?>
lineBlock [ " " ] <>
lineBlock [ " " , " a " , " b " , " " ] <>
lineBlock [ " " ]
2014-12-01 17:27:51 +01:00
, " quoted literal block using > " =: " :: \ n \ n > quoted \ n > block \ n \ n Ordinary paragraph "
=?> codeBlock " > quoted \ n > block " <> para " Ordinary paragraph "
, " quoted literal block using | (not a line block) " =: " :: \ n \ n | quoted \ n | block \ n \ n Ordinary paragraph "
=?> codeBlock " | quoted \ n | block " <> para " Ordinary paragraph "
2014-12-11 18:14:03 +01:00
, " class directive with single paragraph " =: " .. class:: special \ n \ n This is a \ " special \ " paragraph. "
=?> divWith ( " " , [ " special " ] , [] ) ( para " This is a \ " special \ " paragraph. " )
, " class directive with two paragraphs " =: " .. class:: exceptional remarkable \ n \ n First paragraph. \ n \ n Second paragraph. "
=?> divWith ( " " , [ " exceptional " , " remarkable " ] , [] ) ( para " First paragraph. " <> para " Second paragraph. " )
, " class directive around literal block " =: " .. class:: classy \ n \ n :: \ n \ n a \ n b "
=?> divWith ( " " , [ " classy " ] , [] ) ( codeBlock " a \ n b " ) ]
, testGroup " interpreted text roles "
[ " literal role prefix " =: " :literal:`a` " =?> para ( code " a " )
, " literal role postfix " =: " `a`:literal: " =?> para ( code " a " )
, " literal text " =: " ``text`` " =?> para ( code " text " )
2019-01-08 20:36:33 +01:00
, " code role " =: " :code:`a` " =?> para ( codeWith ( " " , [] , [] ) " a " )
2014-12-11 18:14:03 +01:00
, " inherited code role " =: " .. role:: codeLike(code) \ n \ n :codeLike:`a` "
2019-01-08 20:36:33 +01:00
=?> para ( codeWith ( " " , [ " codeLike " ] , [] ) " a " )
2014-12-11 18:14:03 +01:00
, " custom code role with language field "
=: " .. role:: lhs(code) \ n :language: haskell \ n \ n :lhs:`a` "
2019-01-08 20:36:33 +01:00
=?> para ( codeWith ( " " , [ " lhs " , " haskell " ] , [] ) " a " )
2021-11-19 02:33:57 +01:00
, " custom role with class field "
=: " .. role:: classy \ n :class: myclass \ n \ n :classy:`a` "
=?> para ( spanWith ( " " , [ " myclass " ] , [] ) " a " )
, " custom role with class field containing multiple whitespace-separated classes "
=: " .. role:: classy \ n :class: myclass1 myclass2 \ n myclass3 \ n \ n :classy:`a` "
=?> para ( spanWith ( " " , [ " myclass1 " , " myclass2 " , " myclass3 " ] , [] ) " a " )
, " custom role with inherited class field "
=: " .. role:: classy \ n :class: myclass1 \ n .. role:: classier(classy) \ n :class: myclass2 \ n \ n :classier:`a` "
=?> para ( spanWith ( " " , [ " myclass2 " , " myclass1 " ] , [] ) " a " )
2014-12-11 18:14:03 +01:00
, " custom role with unspecified parent role "
=: " .. role:: classy \ n \ n :classy:`text` "
=?> para ( spanWith ( " " , [ " classy " ] , [] ) " text " )
, " role with recursive inheritance "
=: " .. role:: haskell(code) \ n .. role:: lhs(haskell) \ n \ n :lhs:`text` "
2019-01-08 20:36:33 +01:00
=?> para ( codeWith ( " " , [ " lhs " , " haskell " ] , [] ) " text " )
2017-08-18 01:01:44 +02:00
, " unknown role " =: " :unknown:`text` " =?>
2018-08-05 18:15:06 +02:00
para ( codeWith ( " " , [ " interpreted-text " ] , [ ( " role " , " unknown " ) ] ) " text " )
2014-12-11 18:14:03 +01:00
]
2016-10-17 15:54:06 +02:00
, testGroup " footnotes "
2017-06-10 18:26:44 +02:00
[ " remove space before note " =: T . unlines
2016-10-17 15:54:06 +02:00
[ " foo [1]_ "
, " "
, " .. [1] "
, " bar "
] =?>
2018-03-18 06:00:55 +01:00
para ( " foo " <> note ( para " bar " ) )
2016-10-17 15:54:06 +02:00
]
2018-04-23 08:54:06 +02:00
, testGroup " inlines "
[ " links can contain an URI without being parsed twice (#4581) " =:
" `http://loc <http://loc>`__ " =?>
para ( link " http://loc " " " " http://loc " )
, " inline markup cannot be nested " =:
" **a*b*c** " =?>
para ( strong " a*b*c " )
, " bare URI parsing disabled inside emphasis (#4561) " =:
" *http://location* " =?>
para ( emph ( text " http://location " ) )
2018-09-18 13:24:24 +02:00
, " include newlines " =:
" **before \ n after** " =?>
para ( strong ( text " before \ n after " ) )
2018-04-23 08:54:06 +02:00
]
2011-01-26 18:10:39 +01:00
]