-- | The @TestSupport.TestRunner@ module is used to automatically run unit tests. -- -- Design here is by convention: we will look for tests in the "Test" subdirectory of this package only, -- and tests are assumed to be Haskell source files (.hs or .lhs) whose filenames start with "Test". -- Each is assumed to contain its own @main@ function, and to be runnable as an independent application -- without any command line arguments. -- -- TestRunner currently uses runhaskell only to execute tests, which it assumes is already on the system path. module Tests.TestRunner (runPkgTestsHook) where import Tests.FindFiles import Distribution.PackageDescription (PackageDescription) import Distribution.Simple hiding (runTests) import Distribution.Simple.LocalBuildInfo (LocalBuildInfo) --import Text.Regex.Posix import System.Cmd (system) import System.FilePath import Data.List -- | The hook that a Cabal setup script using "Distribution.Simple" may use to automatically run tests. -- Sample use in Setup.hs: -- -- @ -- import qualified TestSupport.TestRunner as TR -- import Distribution.Simple -- -- main = defaultMainWithHooks simpleUserHooks { runTests = TR.runPkgTestsHook } -- @ runPkgTestsHook :: Args -> Bool -> PackageDescription -> LocalBuildInfo -> IO () runPkgTestsHook _ _ _ _ = runLocalTest -- | Run and test all the files in Tests\src runLocalTest :: IO () runLocalTest = runTests "Tests\\src\\" -- | Automatically runs tests in the package. -- -- runTests looks for all Haskell source files in the given subdirectory whose filename starts with \"Test\". -- These are assumed to be the tests. Each is assumed to contain its own @main@ function, and to be runnable -- as an independent application without command line arguments. -- -- Note that no provision is currently made for tests that hang, or for tests that return some status code. -- Just your basic stomp-through for now. runTests :: FilePath -- ^ the starting directory to search in -> IO () runTests startPath = do files <- findFiles startPath isTest mapM_ runTest files where isTest :: FilePath -> Bool isTest fpath = let filename = (takeFileName fpath) in "Test_" `isPrefixOf` filename && ".hs" `isSuffixOf` filename -- | Runs a test. The test is assumed to contain its own @main@ function, and to be runnable as an independent -- application without command line arguments. -- -- This uses runhaskell to execute tests, which it assumes is already on the system path. -- -- /TODO:/ get Cabal to require and configure the location of runhaskell for us? runTest :: FilePath -- ^ the path of the source file to run -> IO () runTest test = putStrLn ( "[Running test: " ++ test ++ "]" ) >> system ("hs2lib " ++ test) >> return () -- >> system ("hs2lib -v2 " ++ test ++ " > " ++ test ++ ".log") >> return ()