packages feed

capability-0.1.0.0: examples/Test/Common.hs

module Test.Common
  ( shouldPrint
  , shouldNotPrint
  , withInput
  ) where

import GHC.IO.Handle (hDuplicate, hDuplicateTo)
import System.IO
import System.IO.Silently (capture_)
import System.IO.Temp (withSystemTempFile)
import Test.Hspec
import UnliftIO.Exception (bracket)


shouldPrint :: IO a -> String -> IO ()
shouldPrint action expected = do
  actual <- capture_ action
  actual `shouldBe` expected


shouldNotPrint :: IO a -> String -> IO ()
shouldNotPrint action expected = do
  actual <- capture_ action
  actual `shouldNotBe` expected


-- | Execute the given action with @stdin@ redirected to read the given input.
withInput :: IO a -> String -> IO a
withInput action input =
  withSystemTempFile "capability-mock-input" $ \tmpFile tmpOut -> do
    -- write input to temp-file
    hPutStr tmpOut input
    hClose tmpOut
    -- read stdin from temp-file
    buffering <- hGetBuffering stdin
    withFile tmpFile ReadMode $ \tmpIn -> do
      let redirect = do
            old <- hDuplicate stdin
            hDuplicateTo tmpIn stdin
            pure old
          restore old = do
            hDuplicateTo old stdin
            hSetBuffering stdin buffering
            hClose old
      bracket redirect restore (\_ -> action)