git.iko.soy/typeable/pandoc
on 3ff41fe 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.Framework
12import Test.Framework.Providers.HUnit
13import Test.HUnit (assertBool)
14import Tests.Helpers
15import Text.Pandoc
16import Text.Pandoc.Shared (trimr)
17import qualified Text.Pandoc.UTF8 as UTF8
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 -> Test
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 :: Test
52tests = buildTest $ 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) -> IO Test
71runCommandTest pandocpath (num, code) = do
72 let codelines = lines code
73 let (continuations, r1) = span ("\\" `isSuffixOf`) codelines
74 let (cmd, r2) = (dropPercent (unwords (map init continuations ++ take 1 r1)),
75 drop 1 r1)
76 let (inplines, r3) = break (=="^D") r2
77 let normlines = takeWhile (/=".") (drop 1 r3)
78 let input = unlines inplines
79 let norm = unlines normlines
80 let shcmd = trimr $ takeDirectory pandocpath </> cmd
81 return $ runTest ("#" ++ show num) shcmd input norm
83extractCommandTest :: FilePath -> Test
84extractCommandTest fp = buildTest $ 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 cases <- mapM (runCommandTest pandocpath) $ zip [1..] codeblocks
91 return $ testGroup fp cases