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