1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
|
{-# LANGUAGE LambdaCase #-}
module Network.WaiSpec (spec) where
import Test.Hspec
import Test.Hspec.QuickCheck (prop)
import Network.Wai
import Data.Word (Word8)
import Data.IORef
import qualified Data.ByteString as S
import qualified Data.ByteString.Lazy as L
import Data.ByteString.Builder (Builder, toLazyByteString, word8)
import Control.Monad (forM_)
spec :: Spec
spec = do
describe "responseToStream" $ do
let getBody res = do
let (_, _, f) = responseToStream res
f $ \streamingBody -> do
builderRef <- newIORef mempty
let add :: Builder -> IO ()
add b = atomicModifyIORef builderRef $ \builder ->
(builder `mappend` b, ())
flush :: IO ()
flush = return ()
streamingBody add flush
L.toStrict . toLazyByteString <$> readIORef builderRef
prop "responseLBS" $ \bytes -> do
body <- getBody $ responseLBS undefined undefined $ L.pack bytes
body `shouldBe` S.pack bytes
prop "responseBuilder" $ \bytes -> do
body <- getBody $ responseBuilder undefined undefined
$ mconcat $ map word8 bytes
body `shouldBe` S.pack bytes
prop "responseStream" $ \chunks -> do
body <- getBody $ responseStream undefined undefined $ \sendChunk _ ->
forM_ chunks $ \chunk -> sendChunk $ mconcat $ map word8 chunk
body `shouldBe` S.concat (map S.pack chunks)
it "responseFile total" $ do
let fp = "wai.cabal"
body <- getBody $ responseFile undefined undefined fp Nothing
expected <- S.readFile fp
body `shouldBe` expected
prop "responseFile partial" $ \offset' count' -> do
let fp = "wai.cabal"
totalBS <- S.readFile fp
let total = S.length totalBS
offset = abs offset' `mod` total
count = abs count' `mod` (total - offset)
body <- getBody $ responseFile undefined undefined fp $ Just FilePart
{ filePartOffset = fromIntegral offset
, filePartByteCount = fromIntegral count
, filePartFileSize = fromIntegral total
}
let expected = S.take count $ S.drop offset totalBS
body `shouldBe` expected
describe "lazyRequestBody" $ do
prop "works" $ \chunks -> do
req <- mkRequestFromChunks chunks
body <- lazyRequestBody req
body `shouldBe` L.fromChunks (map S.pack chunks)
it "is lazy" $ do
let req = setRequestBodyChunks (error "requestBody") defaultRequest
_ <- lazyRequestBody req
return ()
describe "strictRequestBody" $ do
prop "works" $ \chunks -> do
req <- mkRequestFromChunks chunks
body <- strictRequestBody req
body `shouldBe` L.fromChunks (map S.pack chunks)
mkRequestFromChunks :: [[Word8]] -> IO Request
mkRequestFromChunks chunks = do
ref <- newIORef $ map S.pack $ filter (not . null) chunks
pure $
flip setRequestBodyChunks defaultRequest $
atomicModifyIORef ref $ \case
[] -> ([], S.empty)
x:y -> (y, x)
|