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
|
{-# Language OverloadedStrings #-}
module Tests.Lua ( tests ) where
import Control.Monad (when)
import System.FilePath ((</>))
import Test.Tasty (TestTree, localOption)
import Test.Tasty.HUnit (Assertion, assertEqual, testCase)
import Test.Tasty.QuickCheck (ioProperty, testProperty, QuickCheckTests(..))
import Text.Pandoc.Arbitrary ()
import Text.Pandoc.Builder ( (<>), bulletList, doc, doubleQuoted, emph
, linebreak, rawBlock, singleQuoted, para, plain
, space, str, strong)
import Text.Pandoc.Class (runIOorExplode)
import Text.Pandoc.Definition (Block, Inline, Meta, Pandoc)
import Text.Pandoc.Lua
import Foreign.Lua
tests :: [TestTree]
tests = map (localOption (QuickCheckTests 20))
[ testProperty "inline elements can be round-tripped through the lua stack" $
\x -> ioProperty (roundtripEqual (x::Inline))
, testProperty "block elements can be round-tripped through the lua stack" $
\x -> ioProperty (roundtripEqual (x::Block))
, testProperty "meta blocks can be round-tripped through the lua stack" $
\x -> ioProperty (roundtripEqual (x::Meta))
, testProperty "documents can be round-tripped through the lua stack" $
\x -> ioProperty (roundtripEqual (x::Pandoc))
, testCase "macro expansion via filter" $
assertFilterConversion "a '{{helloworld}}' string is expanded"
"strmacro.lua"
(doc . para $ str "{{helloworld}}")
(doc . para . emph $ str "Hello, World")
, testCase "convert all plains to paras" $
assertFilterConversion "plains become para"
"plain-to-para.lua"
(doc $ bulletList [plain (str "alfa"), plain (str "bravo")])
(doc $ bulletList [para (str "alfa"), para (str "bravo")])
, testCase "make hello world document" $
assertFilterConversion "Document contains 'Hello, World!'"
"hello-world-doc.lua"
(doc . para $ str "Hey!" <> linebreak <> str "What's up?")
(doc . para $ str "Hello," <> space <> str "World!")
, testCase "implicit doc filter" $
assertFilterConversion "Document contains 'Hello, World!'"
"implicit-doc-filter.lua"
(doc . plain $ linebreak)
(doc . para $ str "Hello," <> space <> str "World!")
, testCase "parse raw markdown blocks" $
assertFilterConversion "raw markdown block is converted"
"markdown-reader.lua"
(doc $ rawBlock "markdown" "*charly* **delta**")
(doc . para $ emph "charly" <> space <> strong "delta")
, testCase "allow shorthand functions for quote types" $
assertFilterConversion "single quoted becomes double quoted string"
"single-to-double-quoted.lua"
(doc . para . singleQuoted $ str "simple")
(doc . para . doubleQuoted $ str "simple")
, testCase "Count inlines via metatable catch-all" $
assertFilterConversion "filtering with metatable catch-all failed"
"metatable-catch-all.lua"
(doc . para $ "four words, three spaces")
(doc . para $ str "7")
, testCase "Count blocks via Block-specific catch-all" $
assertFilterConversion "filtering with Block catch-all failed"
"block-count.lua"
(doc $ para "one" <> para "two")
(doc $ para "2")
]
assertFilterConversion :: String -> FilePath -> Pandoc -> Pandoc -> Assertion
assertFilterConversion msg filterPath docIn docExpected = do
docEither <- runIOorExplode $
runLuaFilter (Just "../data") ("lua" </> filterPath) [] docIn
case docEither of
Left _ -> fail "lua filter failed"
Right docRes -> assertEqual msg docExpected docRes
roundtripEqual :: (Eq a, FromLuaStack a, ToLuaStack a) => a -> IO Bool
roundtripEqual x = (x ==) <$> roundtripped
where
roundtripped :: (FromLuaStack a, ToLuaStack a) => IO a
roundtripped = runLua $ do
openlibs
pushPandocModule (Just "../data")
setglobal "pandoc"
oldSize <- gettop
push x
size <- gettop
when ((size - oldSize) /= 1) $
error ("not exactly one additional element on the stack: " ++ show size)
res <- peekEither (-1)
case res of
Left _ -> error "could not read from stack"
Right y -> return y
|