packages feed

qudb-0.0.0: test/Test.lhs

#!/usr/bin/env runhaskell

\begin{code}

import System.Directory
import System.Process
import System.IO
import qualified Control.Exception as E
import Data.List
import Control.Monad

data Result = OK | Failure String deriving (Show)

main = do dir <- getCurrentDirectory
          inPlace <- doesFileExist $ dir ++ "/Test.lhs"
          if inPlace
            then runTests >>= printResults
            else do setCurrentDirectory $ dir ++ "/test"
                    main

testFiles :: IO [FilePath]
testFiles = fmap (filter (".sql" `isSuffixOf`)) allFiles
  where allFiles = getCurrentDirectory >>= getDirectoryContents

runTests = do files <- testFiles
              results <- mapM runTest files
              putStrLn ""
              return $ zip files results

runTest fn = run `E.catch` handle
  where run = do code <- readFile fn
                 expectation <- sqlite3 code
                 result <- qudb code
                 if expectation == result
                   then putStr "." >> return OK
                   else diff expectation result >>= fail
        handle :: E.SomeException -> IO Result
        handle ex = fail $ show ex
        fail msg = putStr "F" >> return (Failure msg)

diff expectation result = do f1 <- writeToFile expectation "sqlite3.txt"
                             f2 <- writeToFile result "qudb.txt"
                             diffOutput <- runDiff f1 f2
                             removeFile f1
                             removeFile f2
                             return diffOutput
  where writeToFile str pattern = do tmpDir <- getTemporaryDirectory
                                     (fn, h) <- openTempFile tmpDir pattern
                                     hPutStr h str
                                     hClose h
                                     return fn
        runDiff f1 f2 = do (_, out, _) <- readProcessWithExitCode "colordiff" ["-u", f1, f2] ""
                           return out

sqlite3 = readProcess "sqlite3" []

qudbPath = "../dist/build/qudb/qudb"

qudb = readProcess qudbPath []

printResults results = do printSummary
                          mapM_ printDetails failures
  where failures = filter (\r -> case snd r of OK -> False;  _ -> True) results
        failCount = length failures
        printSummary = unless (null failures) $
                         putStrLn $ show failCount ++ " " ++ plural ++ " failed"
        plural = if failCount == 1 then "test" else "tests"
        printDetails (test, (Failure err)) =
          putStrLn $ "\n" ++ indent (test : lines err) ++ "\n"
        indent lines = "  " ++ intercalate "\n  " lines

\end{code}