11module Main where
22
3- import Control.Monad (forM )
3+ import Control.Monad (forM , filterM )
44import qualified Data.ByteString.Lazy as LBS
55import Data.List (isPrefixOf , isSuffixOf , isInfixOf , sort )
66import Data.Ord (Down (.. ))
@@ -54,25 +54,29 @@ main = do
5454-- Files are ordered by: modification date (newest first), then golden value
5555-- modification date (newest first), then alphabetically.
5656discoverSucceedTests :: FilePath -> FilePath -> IO [TestTree ]
57- discoverSucceedTests testDir buildDir = do
58- agdaFiles <- findAgdaFilesRecursive (testDir </> " Succeed" )
59- sortedFiles <- sortByModTime agdaFiles (\ f -> dropExtension f ++ " .hs" )
60- forM sortedFiles $ \ agdaFile -> do
61- let testName = dropExtension (makeRelative (testDir </> " Succeed" ) agdaFile)
62- goldenFile = dropExtension agdaFile ++ " .hs"
63- return $ succeedTest testDir buildDir testName agdaFile goldenFile
57+ discoverSucceedTests testDir buildDir =
58+ discoverTests testDir buildDir " Succeed" " .hs" succeedTest
6459
6560-- | Discover all .agda files under the Fail directory.
6661-- Files are ordered by: modification date (newest first), then golden value
6762-- modification date (newest first), then alphabetically.
6863discoverFailTests :: FilePath -> FilePath -> IO [TestTree ]
69- discoverFailTests testDir buildDir = do
70- agdaFiles <- findAgdaFilesRecursive (testDir </> " Fail" )
71- sortedFiles <- sortByModTime agdaFiles (\ f -> dropExtension f ++ " .err" )
64+ discoverFailTests testDir buildDir =
65+ discoverTests testDir buildDir " Fail" " .err" failTest
66+
67+ -- | Generic test discovery function.
68+ -- Takes the directory name, golden file extension, and test function.
69+ discoverTests :: FilePath -> FilePath -> String -> String
70+ -> (FilePath -> FilePath -> String -> FilePath -> FilePath -> TestTree )
71+ -> IO [TestTree ]
72+ discoverTests testDir buildDir dirName goldenExt testFn = do
73+ let dir = testDir </> dirName
74+ agdaFiles <- findAgdaFiles dir
75+ sortedFiles <- sortByModTime agdaFiles (\ f -> dropExtension f ++ goldenExt)
7276 forM sortedFiles $ \ agdaFile -> do
73- let testName = dropExtension (makeRelative (testDir </> " Fail " ) agdaFile)
74- goldenFile = dropExtension agdaFile ++ " .err "
75- return $ failTest testDir buildDir testName agdaFile goldenFile
77+ let testName = dropExtension (makeRelative dir agdaFile)
78+ goldenFile = dropExtension agdaFile ++ goldenExt
79+ return $ testFn testDir buildDir testName agdaFile goldenFile
7680
7781-- | Sort files by modification time (newest first), then by golden value
7882-- modification time (if it exists), then alphabetically.
@@ -90,16 +94,15 @@ sortByModTime files goldenPath = do
9094 return $ map (\ (_,_,f) -> f) $ sort filesWithTimes
9195
9296-- | Find all .agda files recursively in a directory.
93- findAgdaFilesRecursive :: FilePath -> IO [FilePath ]
94- findAgdaFilesRecursive dir = do
95- contents <- listDirectory dir
96- paths <- forM contents $ \ name -> do
97- let path = dir </> name
98- isDir <- doesDirectoryExist path
99- if isDir
100- then findAgdaFilesRecursive path
101- else return [path | " .agda" `isSuffixOf` name]
102- return (concat paths)
97+ findAgdaFiles :: FilePath -> IO [FilePath ]
98+ findAgdaFiles dir = do
99+ entries <- listDirectory dir
100+ let paths = map (dir </> ) entries
101+ files <- filterM doesFileExist paths
102+ dirs <- filterM doesDirectoryExist paths
103+ let agdaFiles = filter (" .agda" `isSuffixOf` ) files
104+ subFiles <- concat <$> mapM findAgdaFiles dirs
105+ return $ agdaFiles ++ subFiles
103106
104107-- | Create a test for a succeed case.
105108-- Runs agda2hs on the .agda file, compares the output .hs to the golden file,
@@ -184,7 +187,7 @@ relativizePaths = unlines . map relativizeLine . lines
184187 -- and replace with test/Foo.agda:line:col or just Foo.agda:line:col
185188 case break (== ' /' ) line of
186189 (prefix, ' /' : rest) ->
187- if " test/ " `isInfixOf` rest || " Fail/" `isInfixOf` rest || " Succeed/" `isInfixOf` rest
190+ if any ( `isInfixOf` rest) [ " test/ " , " Fail/" , " Succeed/" ]
188191 then prefix ++ extractRelativePath rest
189192 else line
190193 _ -> line
@@ -200,7 +203,9 @@ relativizePaths = unlines . map relativizeLine . lines
200203 findTestPrefix s
201204 | " test/" `isPrefixOf` s = Just s
202205 | null s = Nothing
203- | otherwise = findTestPrefix (drop 1 s)
206+ | otherwise = case break (== ' /' ) s of
207+ (_, ' /' : rest) -> findTestPrefix rest
208+ _ -> Nothing
204209
205210-- | Diff command for golden tests.
206211diffCmd :: FilePath -> FilePath -> [String ]
0 commit comments