git.iko.soy/typeable/pandoc
on ebbaf2e help sign in
92 lines 3.5 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 files <- filter (".md" `isSuffixOf`) <$>
54 getDirectoryContents "command"
55 let cmds = map extractCommandTest files
56 return $ testGroup "Command:" cmds
58isCodeBlock :: Block -> Bool
59isCodeBlock (CodeBlock _ _) = True
60isCodeBlock _ = False
62extractCode :: Block -> String
63extractCode (CodeBlock _ code) = code
64extractCode _ = ""
66dropPercent :: String -> String
67dropPercent ('%':xs) = dropWhile (== ' ') xs
68dropPercent xs = xs
70runCommandTest :: FilePath -> (Int, String) -> TestTree
71runCommandTest pandocpath (num, code) =
72 let codelines = lines code
73 (continuations, r1) = span ("\\" `isSuffixOf`) codelines
74 (cmd, r2) = (dropPercent (unwords (map init continuations ++ take 1 r1)),
75 drop 1 r1)
76 (inplines, r3) = break (=="^D") r2
77 normlines = takeWhile (/=".") (drop 1 r3)
78 input = unlines inplines
79 norm = unlines normlines
80 shcmd = trimr $ takeDirectory pandocpath </> cmd
81 in runTest ("#" ++ show num) shcmd input norm
83extractCommandTest :: FilePath -> TestTree
84extractCommandTest fp = unsafePerformIO $ do
85 pandocpath <- findPandoc
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