forked from lylek/vintage-basic
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrun_tests.hs
More file actions
executable file
·82 lines (71 loc) · 3.17 KB
/
run_tests.hs
File metadata and controls
executable file
·82 lines (71 loc) · 3.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#!/usr/local/bin/runhaskell
import Data.Array ((!))
import Data.List (intersperse)
import Data.Maybe (catMaybes)
import System.Process (system)
import System.Directory (doesDirectoryExist,getCurrentDirectory,getDirectoryContents,removeFile)
import System.FilePath ((</>))
import System.Environment (getArgs)
import Text.Regex.Base
import Text.Regex.Posix
testFilePat = makeRegex "^.*_test.hs$" :: Regex
testFuncPat = makeRegex "^ *(test_[A-Za-z0-9_']*) *=" :: Regex
testModuleNamePat = makeRegex "^ *module *([A-Za-z0-9_'.]*)" :: Regex
main = do
args <- getArgs
testModulePaths <- if null args then findModulePaths else return args
putStrLn "Running tests in files:"
sequence_ [putStrLn (" " ++ testModulePath) | testModulePath <- testModulePaths]
putStrLn ""
putStrLn "Tests found:"
modulesWithTests <-
sequence [do moduleCode <- readFile testModulePath
let testModule = findModuleName moduleCode
putStrLn (" " ++ testModule)
let tests = findTests moduleCode
sequence_ [putStrLn (" " ++ test) | test <- tests]
return (testModule, findTests moduleCode)
| testModulePath <- testModulePaths]
let testCode = genTestDriver modulesWithTests
writeFile "test_driver.hs" testCode
system ("runhaskell -itest -isrc test_driver.hs")
removeFile "test_driver.hs"
findFilesInSubdirs :: FilePath -> IO [String]
findFilesInSubdirs dir = do
files <- getDirectoryContents dir
let paths = [dir </> file | file <- filter (`notElem` [".", ".."]) files]
paths' <- sequence [do { t <- doesDirectoryExist path; if t then findFilesInSubdirs path else return [] } | path <- paths]
return $ concat (paths : paths')
findModulePaths :: IO [String]
findModulePaths = do
files <- findFilesInSubdirs "test"
return $ map head $ concat [match testFilePat file | file <- files]
matchTextToSubstring :: MatchText String -> String
matchTextToSubstring mt = fst (mt ! 1)
findModuleName :: String -> String
findModuleName str =
case matchOnceText testModuleNamePat str of
Nothing -> error "Unable to find module name in file"
(Just (_, mt, _)) -> matchTextToSubstring mt
findTests :: String -> [String]
findTests str = [matchTextToSubstring mt | mt <- matchAllText testFuncPat str]
genTestDriver modulesWithTests =
"import System.Exit\n"
++ "import Test.HUnit\n"
++ concat [genImport testModule | (testModule,_) <- modulesWithTests]
++ "\n"
++ "main = do\n"
++ " (Counts cases tried errors failures) <- runTestTT $\n"
++ " TestList [\n"
++ concat (intersperse ",\n"
[genTest testModule testFunc
| (testModule,testFuncs) <- modulesWithTests, testFunc <- testFuncs])
++ "\n"
++ " ]\n"
++ " exitWith $ if errors > 0 || failures > 0\n"
++ " then ExitFailure (errors+failures)\n"
++ " else ExitSuccess\n"
genImport testModule = "import qualified " ++ testModule ++ "\n"
genTest testModule testFunc =
let qualifiedTest = testModule ++ "." ++ testFunc
in " TestLabel \"" ++ qualifiedTest ++ "\" " ++ qualifiedTest