@@ -0,0 +1,91 @@
1+module Tests.Command (findPandoc, runTest, tests)
2+where
3+
4+import Test.Framework (testGroup, Test )
5+import Test.Framework.Providers.HUnit
6+import Test.HUnit ( assertBool )
7+import System.Environment.Executable (getExecutablePath)
8+import System.FilePath ( (</>), takeDirectory, splitDirectories,
9+ joinPath )
10+import System.Directory
11+import System.Exit
12+import Data.Algorithm.Diff
13+import Prelude hiding ( readFile )
14+import qualified Text.Pandoc.UTF8 as UTF8
15+import Text.Printf
16+import Text.Pandoc.Process (pipeProcess)
17+
18+data TestResult = TestPassed
19+ | TestError ExitCode
20+ | TestFailed String FilePath [Diff String]
21+ deriving (Eq)
22+
23+instance Show TestResult where
24+ show TestPassed = "PASSED"
25+ show (TestError ec) = "ERROR " ++ show ec
26+ show (TestFailed cmd file d) = '\n' : dash ++
27+ "\n--- " ++ file ++
28+ "\n+++ " ++ cmd ++ "\n" ++ showDiff (1,1) d ++
29+ dash
30+ where dash = replicate 72 '-'
31+
32+showDiff :: (Int,Int) -> [Diff String] -> String
33+showDiff _ [] = ""
34+showDiff (l,r) (First ln : ds) =
35+ printf "+%4d " l ++ ln ++ "\n" ++ showDiff (l+1,r) ds
36+showDiff (l,r) (Second ln : ds) =
37+ printf "-%4d " r ++ ln ++ "\n" ++ showDiff (l,r+1) ds
38+showDiff (l,r) (Both _ _ : ds) =
39+ showDiff (l+1,r+1) ds
40+
41+-- | Find pandoc executable relative to test-pandoc
42+-- First, try in same directory (e.g. if both in ~/.cabal/bin)
43+-- Second, try ../pandoc (e.g. if in dist/XXX/build/test-pandoc)
44+findPandoc :: IO FilePath
45+findPandoc = do
46+ testExePath <- getExecutablePath
47+ let testExeDir = takeDirectory testExePath
48+ found <- doesFileExist (testExeDir </> "pandoc")
49+ return $ if found
50+ then testExeDir </> "pandoc"
51+ else case splitDirectories testExeDir of
52+ [] -> error "test-pandoc: empty testExeDir"
53+ xs -> joinPath (init xs) </> "pandoc" </> "pandoc"
54+
55+-- | Run a test with normalize function, return True if test passed.
56+runTest :: FilePath -- ^ pandoc executable path
57+ -> String -- ^ Title of test
58+ -> [String] -- ^ Options to pass to pandoc
59+ -> String -- ^ Input text
60+ -> String -- ^ Expected output
61+ -> Test
62+runTest pandocPath testname opts inp norm = testCase testname $ do
63+ let options = ["--quiet", "--data-dir", ".." </> "data"] ++ opts
64+ let cmd = unwords ((pandocPath </> "pandoc") : options)
65+ let findDynlibDir [] = Nothing
66+ findDynlibDir ("build":xs) = Just $ joinPath (reverse xs) </> "build"
67+ findDynlibDir (_:xs) = findDynlibDir xs
68+ let mbDynlibDir = findDynlibDir (reverse $ splitDirectories pandocPath)
69+ let dynlibEnv = case mbDynlibDir of
70+ Nothing -> []
71+ Just d -> [("DYLD_LIBRARY_PATH", d),
72+ ("LD_LIBRARY_PATH", d)]
73+ let env = dynlibEnv ++ [("TMP","."),("LANG","en_US.UTF-8"),("HOME", "./")]
74+ (ec, outbs) <- pipeProcess (Just env) pandocPath options
75+ (UTF8.fromStringLazy inp)
76+ -- filter \r so the tests will work on Windows machines
77+ let out = filter (/= '\r') $ UTF8.toStringLazy outbs
78+ result <- if ec == ExitSuccess
79+ then do
80+ if out == norm
81+ then return TestPassed
82+ else return
83+ $ TestFailed cmd "expected"
84+ $ getDiff (lines out) (lines norm)
85+ else return $ TestError ec
86+ assertBool (show result) (result == TestPassed)
87+
88+tests :: [Test]
89+tests = [ testGroup "commands"
90+ [ ]
91+ ]