{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeApplications #-} module Main where import Effectful import Effectful.Temporary import System.IO.Error (isDoesNotExistError) import qualified Utils as U import Effectful.Process.Typed import Test.Tasty.HUnit (Assertion, testCase) import Test.Tasty (defaultMain, testGroup) main :: IO () main = defaultMain $ testGroup "typed-process-effectful" [ testCase "Existing executable" testExistingExecutable , testCase "Non-existent executable" testNonExistentExecutable , testCase "Continue process execution" testContinueProcessExecution , testCase "Terminate process" testTerminateProcess , testCase "Wait for process" testWaitForProcess , testCase "Helper functions" testHelperFunctions , testCase "Exit Codes" testExitCodes ] testExistingExecutable :: Assertion testExistingExecutable = runEff $ do let pc = proc "/usr/bin/env" ["true"] action = runTypedProcess $ do p <- startProcess pc waitExitCode p result <- action U.assertEqual "Executable exists" ExitSuccess result testNonExistentExecutable :: Assertion testNonExistentExecutable = runEff $ do let pc = proc "/bin/doesnotexist" [] let action = runTypedProcess $ do p <- startProcess pc waitExitCode p U.assertException (runEff action) isDoesNotExistError testContinueProcessExecution :: Assertion testContinueProcessExecution = runEff $ do let pc = shell "sleep 3" action = runTypedProcess $ do p <- startProcess pc getExitCode p result <- action U.assertEqual "" result Nothing testTerminateProcess :: Assertion testTerminateProcess = runEff $ do let action = runTemporary . runTypedProcess $ do withSystemTempFile "typed-process-effectful-test" $ \fp h -> do let pc = setStdout (useHandleClose h) $ shell "sleep 1; printf 'Output'" withProcessTerm pc (const $ pure ()) liftIO $ readFile fp result <- action U.assertEqual "" "" result testWaitForProcess :: Assertion testWaitForProcess = runEff $ do let action = runTemporary . runTypedProcess $ do withSystemTempFile "typed-process-effectful-test" $ \fp h -> do let pc = setStdout (useHandleClose h) $ shell "sleep 1; printf 'Output'" withProcessWait pc (const $ pure ()) liftIO $ readFile fp result <- action U.assertEqual "" result "Output" testHelperFunctions :: Assertion testHelperFunctions = runEff $ do let pc = proc "/usr/bin/env" ["true"] action = runTypedProcess $ do runProcess pc result <- action U.assertEqual "" result ExitSuccess let pc2 = proc "/usr/bin/env" ["true"] result2 <- runTypedProcess $ do runProcess_ pc2 U.assertEqual "" result2 () let pc3 = shell "printf 'stdout'; printf 'stderr' >&2" result3 <- runTypedProcess $ do readProcess pc3 U.assertEqual "" result3 (ExitSuccess, "stdout", "stderr") let pc4 = shell "printf 'stdout'; printf 'stderr' >&2" result4 <- runTypedProcess $ do readProcess_ pc4 U.assertEqual "" result4 ("stdout", "stderr") let pc5 = shell "printf 'Output'" result5 <- runTypedProcess $ do readProcessStdout pc5 U.assertEqual "" result5 (ExitSuccess, "Output") let pc6 = shell "printf 'Output'" result6 <- runTypedProcess $ do readProcessStdout pc6 U.assertEqual "" result6 (ExitSuccess, "Output") let pc7 = shell "printf 'Output'" result7 <- runTypedProcess $ do readProcessStdout_ pc7 U.assertEqual "" result7 "Output" let pc8 = shell "printf 'Output' >&2" result8 <- runTypedProcess $ do readProcessStderr pc8 U.assertEqual "" result8 (ExitSuccess, "Output") testExitCodes :: Assertion testExitCodes = runEff $ do let pc = proc "/usr/bin/env" ["false"] action = runEff . runTypedProcess $ do runProcess_ pc U.assertException action (const @_ @ExitCodeException True) let pc2 = proc "/usr/bin/env" ["false"] action2 = runEff . runTypedProcess $ do readProcess_ pc2 U.assertException action2 (const @_ @ExitCodeException True) let pc3 = proc "/usr/bin/env" ["false"] action3 = runEff . runTypedProcess $ do readProcessStdout_ pc3 U.assertException action3 (const @_ @ExitCodeException True) let pc4 = proc "/usr/bin/env" ["false"] action4 = runEff . runTypedProcess $ do readProcessStderr_ pc4 U.assertException action4 (const @_ @ExitCodeException True)