git.iko.soy/typeable/pandoc
on 4bfcbbf help sign in
95 lines 3.8 kB history raw
1module Tests.Command (findPandoc, runTest, tests)
2where
4import Data.Algorithm.Diff
5import Data.List (isSuffixOf)
6import Prelude hiding (readFile)
7import System.Directory
8import System.Exit
9import System.FilePath (joinPath, splitDirectories, takeDirectory, (</>))
10import System.Process
11import System.IO (stderr, hPutStr)
12import Test.Tasty
13import Test.Tasty.HUnit
14import Tests.Helpers
15import Text.Pandoc
16import qualified Data.ByteString as BS
17import qualified Text.Pandoc.UTF8 as UTF8
18import System.IO.Unsafe (unsafePerformIO) -- TODO temporary
20-- | Run a test with normalize function, return True if test passed.
21runTest :: String -- ^ Title of test
22 -> FilePath -- ^ Path to pandoc
23 -> String -- ^ Shell command
24 -> String -- ^ Input text
25 -> String -- ^ Expected output
26 -> TestTree
27runTest testname pandocpath cmd inp norm = testCase testname $ do
28 let findDynlibDir [] = Nothing
29 findDynlibDir ("build":xs) = Just $ joinPath (reverse xs) </> "build"
30 findDynlibDir (_:xs) = findDynlibDir xs
31 let mbDynlibDir = findDynlibDir (reverse $ splitDirectories $
32 takeDirectory $ takeWhile (/=' ') cmd)
33 let dynlibEnv = case mbDynlibDir of
34 Nothing -> []
35 Just d -> [("DYLD_LIBRARY_PATH", d),
36 ("LD_LIBRARY_PATH", d)]
37 let env' = dynlibEnv ++ [("PATH",takeDirectory pandocpath),("TMP","."),("LANG","en_US.UTF-8"),("HOME", "./"),("pandoc_datadir", "..")]
38 let pr = (shell cmd){ env = Just env' }
39 (ec, out', err') <- readCreateProcessWithExitCode pr inp
40 -- filter \r so the tests will work on Windows machines
41 let out = filter (/= '\r') $ err' ++ out'
42 result <- if ec == ExitSuccess
43 then do
44 if out == norm
45 then return TestPassed
46 else return
47 $ TestFailed cmd "expected"
48 $ getDiff (lines out) (lines norm)
49 else do
50 hPutStr stderr err'
51 return $ TestError ec
52 assertBool (show result) (result == TestPassed)
54tests :: TestTree
55tests = unsafePerformIO $ do
56 pandocpath <- findPandoc
57 files <- filter (".md" `isSuffixOf`) <$>
58 getDirectoryContents "command"
59 let cmds = map (extractCommandTest pandocpath) files
60 return $ testGroup "Command:" cmds
62isCodeBlock :: Block -> Bool
63isCodeBlock (CodeBlock _ _) = True
64isCodeBlock _ = False
66extractCode :: Block -> String
67extractCode (CodeBlock _ code) = code
68extractCode _ = ""
70dropPercent :: String -> String
71dropPercent ('%':xs) = dropWhile (== ' ') xs
72dropPercent xs = xs
74runCommandTest :: FilePath -> (Int, String) -> TestTree
75runCommandTest pandocpath (num, code) =
76 let codelines = lines code
77 (continuations, r1) = span ("\\" `isSuffixOf`) codelines
78 (cmd, r2) = (dropPercent (unwords (map init continuations ++ take 1 r1)),
79 drop 1 r1)
80 (inplines, r3) = break (=="^D") r2
81 normlines = takeWhile (/=".") (drop 1 r3)
82 input = unlines inplines
83 norm = unlines normlines
84 shcmd = cmd -- trimr $ takeDirectory pandocpath </> cmd
85 in runTest ("#" ++ show num) pandocpath shcmd input norm
87extractCommandTest :: FilePath -> FilePath -> TestTree
88extractCommandTest pandocpath fp = unsafePerformIO $ do
89 contents <- UTF8.toText <$> BS.readFile ("command" </> fp)
90 Pandoc _ blocks <- runIOorExplode (readMarkdown
91 def{ readerExtensions = pandocExtensions } contents)
92 let codeblocks = map extractCode $ filter isCodeBlock $ blocks
93 let cases = map (runCommandTest pandocpath) $ zip [1..] codeblocks
94 return $ testGroup fp cases