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