{-# LANGUAGE OverloadedStrings #-} {- | Module : Main Description : Simple process testing Copyright : (c) Ivan Lazar Miljenovic License : MIT Maintainer : Ivan.Miljenovic@gmail.com This will probably only run on *nix systems. -} module Main (main) where import Streaming.Process import qualified Data.ByteString.Lazy as LB import Data.ByteString.Streaming (ByteString) import qualified Data.ByteString.Streaming as B import Streaming (Of(..)) import Test.Hspec (describe, hspec) import Test.Hspec.QuickCheck (prop) import Test.QuickCheck (Property, ioProperty) import Test.QuickCheck.Instances () -------------------------------------------------------------------------------- main :: IO () main = hspec $ describe "cat" $ do prop "stdout only" prop_cat prop "stdout and stderr" prop_catBoth -- Use lazy bytestrings to avoid issues with it being chunked -- differently. -- -- But don't take them as arguments prop_cat :: LB.ByteString -> Property prop_cat bs = ioProperty (noStdErr "cat" (B.fromLazy bs) (fmap (bs==) . B.toLazy_)) prop_catBoth :: LB.ByteString -> Property prop_catBoth bs = ioProperty $ withStreamingCommand "cat | tee /dev/stderr" (B.fromLazy bs) $ fmap (uncurry' ((&&) . isSame)) . B.toLazy . fmap isSame . B.toLazy_ where isSame = (bs==) noStdErr :: String -> ByteString IO r -> (ByteString IO () -> IO v) -> IO v noStdErr cmd inp f = withStreamCommand cmd $ \(StreamProcess stdin stdout ClosedStream) -> snd <$> concurrently (supplyStream stdin inp) (withStream stdout f) uncurry' :: (a -> b -> c) -> Of a b -> c uncurry' f (a :> b) = f a b