git.iko.soy/typeable/pandoc
on ea6be2e help sign in
93 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 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 -> String -- ^ Shell command
23 -> String -- ^ Input text
24 -> String -- ^ Expected output
25 -> TestTree
26runTest testname cmd inp norm = testCase testname $ do
27 let cmd' = cmd ++ " --data-dir ../data"
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 ++ [("TMP","."),("LANG","en_US.UTF-8"),("HOME", "./")]
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 return $ TestError ec
50 assertBool (show result) (result == TestPassed)
52tests :: TestTree
53tests = unsafePerformIO $ do
54 pandocpath <- findPandoc
55 files <- filter (".md" `isSuffixOf`) <$>
56 getDirectoryContents "command"
57 let cmds = map (extractCommandTest pandocpath) files
58 return $ testGroup "Command:" cmds
60isCodeBlock :: Block -> Bool
61isCodeBlock (CodeBlock _ _) = True
62isCodeBlock _ = False
64extractCode :: Block -> String
65extractCode (CodeBlock _ code) = code
66extractCode _ = ""
68dropPercent :: String -> String
69dropPercent ('%':xs) = dropWhile (== ' ') xs
70dropPercent xs = xs
72runCommandTest :: FilePath -> (Int, String) -> TestTree
73runCommandTest pandocpath (num, code) =
74 let codelines = lines code
75 (continuations, r1) = span ("\\" `isSuffixOf`) codelines
76 (cmd, r2) = (dropPercent (unwords (map init continuations ++ take 1 r1)),
77 drop 1 r1)
78 (inplines, r3) = break (=="^D") r2
79 normlines = takeWhile (/=".") (drop 1 r3)
80 input = unlines inplines
81 norm = unlines normlines
82 shcmd = trimr $ takeDirectory pandocpath </> cmd
83 in runTest ("#" ++ show num) shcmd input norm
85extractCommandTest :: FilePath -> FilePath -> TestTree
86extractCommandTest pandocpath fp = unsafePerformIO $ do
87 contents <- UTF8.toText <$> BS.readFile ("command" </> fp)
88 Pandoc _ blocks <- runIOorExplode (readMarkdown
89 def{ readerExtensions = pandocExtensions } contents)
90 let codeblocks = map extractCode $ filter isCodeBlock $ blocks
91 let cases = map (runCommandTest pandocpath) $ zip [1..] codeblocks
92 return $ testGroup fp cases