git.iko.soy/typeable/pandoc
on fa59e2e help sign in
93 lines 3.5 kB history raw
1module Tests.Command (findPandoc, runTest, tests)
2where
4import Tests.Helpers
5import Test.Framework
6import Test.Framework.Providers.HUnit
7import Test.HUnit ( assertBool )
8import System.FilePath ( (</>), takeDirectory, splitDirectories,
9 joinPath )
10import System.Process
11import System.Directory
12import System.Exit
13import Text.Pandoc
14import Data.Algorithm.Diff
15import Prelude hiding ( readFile )
16import qualified Text.Pandoc.UTF8 as UTF8
17import Data.List (isSuffixOf)
18import Text.Pandoc.Shared (trimr)
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 -> Test
26runTest testname cmd inp norm = testCase testname $ do
27 let cmd' = cmd ++ " --quiet --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') 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 :: Test
53tests = buildTest $ do
54 files <- filter (".md" `isSuffixOf`) <$>
55 getDirectoryContents "command"
56 let cmds = map extractCommandTest 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) -> IO Test
72runCommandTest pandocpath (num, code) = do
73 let codelines = lines code
74 let (continuations, r1) = span ("\\" `isSuffixOf`) codelines
75 let (cmd, r2) = (dropPercent (unwords (map init continuations ++ take 1 r1)),
76 drop 1 r1)
77 let (inplines, r3) = break (=="^D") r2
78 let normlines = takeWhile (/=".") (drop 1 r3)
79 let input = unlines inplines
80 let norm = unlines normlines
81 let shcmd = trimr $ takeDirectory pandocpath </> cmd
82 return $ runTest ("#" ++ show num) shcmd input norm
84extractCommandTest :: FilePath -> Test
85extractCommandTest fp = buildTest $ do
86 pandocpath <- findPandoc
87 contents <- UTF8.readFile ("command" </> fp)
88 Pandoc _ blocks <- runIOorExplode (readMarkdown
89 def{ readerExtensions = pandocExtensions } contents)
90 let codeblocks = map extractCode $ filter isCodeBlock $ blocks
91 cases <- mapM (runCommandTest pandocpath) $ zip [1..] codeblocks
92 return $ testGroup fp cases