module Minilang.IOSpec where import Control.Exception (bracket) import Minilang.IO (runEval) import System.Directory (getTemporaryDirectory, removeFile) import System.FilePath ((<.>), ()) import System.IO (IOMode (..), hClose, readFile, withFile, writeFile) import System.Posix (mkstemp) import Test.Hspec (Spec, around, describe, it, parallel, shouldBe) import Prelude hiding (lines, readFile, writeFile) spec :: Spec spec = parallel $ describe "MiniLang I/O Evaluator" $ do around withTempFile $ it "evaluates a simple MiniLang 'program' and dumps result" $ \fileName -> do let outputFileName = fileName <> ".out" program = [ "((lam (x y) x) z t)" ] writeFile fileName (unlines program) _ <- withFile fileName ReadMode $ \hin -> withFile outputFileName AppendMode $ \hout -> runEval hin hout out <- readFile outputFileName out `shouldBe` "Var \"z\"\n" withTempFile :: (String -> IO ()) -> IO () withTempFile = bracket mkTempFile rmTempFile where mkTempFile = getTemporaryDirectory >>= \dir -> mkstemp (dir "test-repl") >>= \(fp, h) -> hClose h >> pure fp rmTempFile fn = removeFile fn >> removeFile (fn <.> "out")