packages feed

typed-process-effectful-1.0.0.2: test/Main.hs

{-# 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 (defaultMain, testGroup)
import Test.Tasty.HUnit (Assertion, testCase)

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)