packages feed

streaming-process-0.1.0.0: test/simple.hs

{-# 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