@@ -6,18 +6,20 @@ module Main where
66import Control.Exception (catch , SomeException )
77import Control.Monad (forM , unless )
88import qualified Data.ByteString.Lazy as LBS
9- import Data.List (intercalate , isPrefixOf , isSuffixOf , sort )
9+ import Data.List (isPrefixOf , isSuffixOf , isInfixOf , sort , tails )
1010import qualified Data.Text as T
1111import qualified Data.Text.Encoding as TE
1212import System.Directory
13- ( doesFileExist
13+ ( createDirectoryIfMissing
14+ , doesFileExist
1415 , getCurrentDirectory
16+ , getTemporaryDirectory
1517 , listDirectory
1618 , removeFile
1719 , setCurrentDirectory
1820 )
1921import System.Exit (ExitCode (.. ))
20- import System.FilePath ((</>) , dropExtension , makeRelative , takeDirectory , takeFileName )
22+ import System.FilePath ((</>) , dropExtension , makeRelative , takeBaseName , takeDirectory , takeFileName )
2123import System.Process (readProcessWithExitCode )
2224import Test.Tasty (TestTree , defaultMain , testGroup )
2325import Test.Tasty.Golden (goldenVsStringDiff )
@@ -35,9 +37,14 @@ main = do
3537 -- Change to the test directory so that agda2hs can find the agda-lib
3638 setCurrentDirectory testDir
3739
40+ -- Create a temporary build directory
41+ tmpDir <- getTemporaryDirectory
42+ let buildDir = tmpDir </> " agda2hs-test-build"
43+ createDirectoryIfMissing True buildDir
44+
3845 -- Discover test cases
39- succeedTests <- discoverSucceedTests testDir
40- failTests <- discoverFailTests testDir
46+ succeedTests <- discoverSucceedTests testDir buildDir
47+ failTests <- discoverFailTests testDir buildDir
4148
4249 -- Run tests
4350 defaultMain $ testGroup " agda2hs"
@@ -46,24 +53,22 @@ main = do
4653 ]
4754
4855-- | Discover all .agda files under the Succeed directory recursively.
49- discoverSucceedTests :: FilePath -> IO [TestTree ]
50- discoverSucceedTests testDir = do
56+ discoverSucceedTests :: FilePath -> FilePath -> IO [TestTree ]
57+ discoverSucceedTests testDir buildDir = do
5158 agdaFiles <- findAgdaFilesRecursive (testDir </> " Succeed" )
5259 forM (sort agdaFiles) $ \ agdaFile -> do
53- let relPath = makeRelative testDir agdaFile
54- testName = dropExtension (makeRelative (testDir </> " Succeed" ) agdaFile)
60+ let testName = dropExtension (makeRelative (testDir </> " Succeed" ) agdaFile)
5561 goldenFile = dropExtension agdaFile ++ " .hs"
56- return $ succeedTest testDir testName relPath goldenFile
62+ return $ succeedTest testDir buildDir testName agdaFile goldenFile
5763
5864-- | Discover all .agda files under the Fail directory.
59- discoverFailTests :: FilePath -> IO [TestTree ]
60- discoverFailTests testDir = do
65+ discoverFailTests :: FilePath -> FilePath -> IO [TestTree ]
66+ discoverFailTests testDir buildDir = do
6167 agdaFiles <- findAgdaFilesRecursive (testDir </> " Fail" )
6268 forM (sort agdaFiles) $ \ agdaFile -> do
63- let relPath = makeRelative testDir agdaFile
64- testName = dropExtension (makeRelative (testDir </> " Fail" ) agdaFile)
69+ let testName = dropExtension (makeRelative (testDir </> " Fail" ) agdaFile)
6570 goldenFile = dropExtension agdaFile ++ " .err"
66- return $ failTest testDir testName relPath goldenFile
71+ return $ failTest testDir buildDir testName agdaFile goldenFile
6772
6873-- | Find all .agda files recursively in a directory.
6974findAgdaFilesRecursive :: FilePath -> IO [FilePath ]
@@ -91,12 +96,20 @@ doesDirectoryExist path = do
9196-- | Create a test for a succeed case.
9297-- Runs agda2hs on the .agda file, compares the output .hs to the golden file,
9398-- then compiles the .hs file with ghc.
94- succeedTest :: FilePath -> String -> FilePath -> FilePath -> TestTree
95- succeedTest testDir testName agdaFile goldenFile =
99+ succeedTest :: FilePath -> FilePath -> String -> FilePath -> FilePath -> TestTree
100+ succeedTest testDir buildDir testName agdaFile goldenFile =
96101 goldenVsStringDiff testName diffCmd goldenFile $ do
97- -- Get the output directory (same as the agda file directory)
98- let outDir = takeDirectory agdaFile
99- succeedDir = testDir </> " Succeed"
102+ let succeedDir = testDir </> " Succeed"
103+ -- Output to build directory to avoid polluting source tree
104+ outDir = buildDir </> " Succeed"
105+ -- Get the relative path from Succeed to the agda file
106+ relAgdaPath = makeRelative succeedDir agdaFile
107+ -- Compute the expected output file path (same relative path, but .hs)
108+ generatedFile = outDir </> dropExtension relAgdaPath ++ " .hs"
109+ generatedDir = takeDirectory generatedFile
110+
111+ -- Ensure output directory exists (including subdirectories)
112+ createDirectoryIfMissing True generatedDir
100113
101114 -- Run agda2hs with include path for Succeed directory
102115 (exitCode, stdout, stderr) <- readProcessWithExitCode
@@ -106,15 +119,14 @@ succeedTest testDir testName agdaFile goldenFile =
106119
107120 case exitCode of
108121 ExitSuccess -> do
109- -- Read the generated .hs file
110- let generatedFile = dropExtension agdaFile ++ " .hs"
122+ -- Read the generated .hs file from build directory
111123 content <- LBS. readFile generatedFile
112124
113125 -- Also run ghc to check the generated code compiles
114126 -- Add include path for finding imported modules
115127 (ghcExit, ghcOut, ghcErr) <- readProcessWithExitCode
116128 " ghc"
117- [" -fno-code" , " -i" ++ succeedDir , generatedFile]
129+ [" -fno-code" , " -i" ++ outDir , generatedFile]
118130 " "
119131
120132 case ghcExit of
@@ -128,17 +140,22 @@ succeedTest testDir testName agdaFile goldenFile =
128140-- | Create a test for a fail case.
129141-- Runs agda2hs on the .agda file, expects it to fail, and compares the error
130142-- message to the golden file.
131- failTest :: FilePath -> String -> FilePath -> FilePath -> TestTree
132- failTest testDir testName agdaFile goldenFile =
143+ failTest :: FilePath -> FilePath -> String -> FilePath -> FilePath -> TestTree
144+ failTest testDir buildDir testName agdaFile goldenFile =
133145 goldenVsStringDiff testName diffCmd goldenFile $ do
134146 let failDir = testDir </> " Fail"
135147 succeedDir = testDir </> " Succeed"
148+ -- Output to build directory to avoid polluting source tree
149+ outDir = buildDir </> " Fail"
150+
151+ -- Ensure output directory exists
152+ createDirectoryIfMissing True outDir
136153
137154 -- Run agda2hs (expecting failure) with include paths for both directories
138155 -- Fail tests may depend on modules from Succeed
139156 (exitCode, stdout, stderr) <- readProcessWithExitCode
140157 " agda2hs"
141- [agdaFile, " -o" , takeDirectory agdaFile , " -v0" , " -i" ++ failDir, " -i" ++ succeedDir]
158+ [agdaFile, " -o" , outDir , " -v0" , " -i" ++ failDir, " -i" ++ succeedDir]
142159 " "
143160
144161 let output = stdout ++ stderr
0 commit comments