{-# LANGUAGE CPP #-} module SaySpec (spec) where import Test.Hspec import Test.Hspec.QuickCheck import Say import Control.Monad (forM_) import Data.Text (pack) import qualified Data.Text.IO as T import System.IO import UnliftIO.Temporary (withSystemTempFile) import qualified Data.ByteString as S import Data.List (nub) encodings :: [TextEncoding] encodings = [utf8, utf16le, utf32be #if MIN_VERSION_base(4, 4, 0) , char8 #endif ] newlines :: [NewlineMode] newlines = nub [ noNewlineTranslation , universalNewlineMode , nativeNewlineMode , NewlineMode CRLF CRLF ] bufferings :: [BufferMode] bufferings = [ NoBuffering , LineBuffering , BlockBuffering Nothing , BlockBuffering $ Just 10 , BlockBuffering $ Just 2048 , BlockBuffering $ Just 30000 ] alts :: [(String, Handle -> String -> IO ())] alts = [ ("String", hPutStrLn) , ("Text", \h -> T.hPutStrLn h . pack) ] spec :: Spec spec = do forM_ encodings $ \encoding -> describe ("Encoding: " ++ show encoding) $ forM_ newlines $ \newline -> describe ("Newline: " ++ show newline) $ forM_ bufferings $ \buffering -> describe ("Buffering: " ++ show buffering) $ forM_ alts $ \(altName, altFunc) -> describe ("Versus: " ++ altName) $ do let prepHandle h = do hSetEncoding h encoding hSetNewlineMode h newline hSetBuffering h buffering test str = withSystemTempFile "say" $ \fpSay handleSay -> withSystemTempFile "alt" $ \fpAlt handleAlt -> do forM_ [(handleSay, \h -> hSay h . pack), (handleAlt, altFunc)] $ \(h, f) -> do prepHandle h f h str hClose h bsSay <- S.readFile fpSay bsAlt <- S.readFile fpAlt bsSay `shouldBe` bsAlt prop "matches" test forM_ [10, 20, 100, 1000, 2047, 2048, 2049, 10000] $ \size -> do it ("size: " ++ show size) $ test $ replicate size 'A'