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
|
{-# LANGUAGE OverloadedStrings #-}
module Data.Conduit.ByteString.BuilderSpec (spec) where
import Test.Hspec
import Test.Hspec.QuickCheck (prop)
import Data.Conduit ((.|), runConduit, Flush (..))
import qualified Data.Conduit.List as CL
import Data.Conduit.ByteString.Builder (builderToByteString, builderToByteStringFlush)
import Control.Monad.ST (runST)
import qualified Data.ByteString as S
import Data.ByteString.Builder (byteString, toLazyByteString)
import Data.ByteString.Builder.Internal (lazyByteStringInsert, flush)
import qualified Data.ByteString.Lazy as L
spec :: Spec
spec =
describe "Data.Conduit.ByteString.Builder" $ do
prop "idempotent to toLazyByteString" $ \bss' -> runST $ do
let bss = map S.pack bss'
let builders = map byteString bss
let lbs = toLazyByteString $ mconcat builders
let src = mconcat $ map (CL.sourceList . return) builders
outBss <- runConduit $ src .| builderToByteString .| CL.consume
return $ lbs == L.fromChunks outBss
it "works for large input" $ do
let builders = replicate 10000 (byteString "hello world!")
let lbs = toLazyByteString $ mconcat builders
let src = mconcat $ map (CL.sourceList . return) builders
outBss <- runConduit $ src .| builderToByteString .| CL.consume
lbs `shouldBe` L.fromChunks outBss
it "works for lazy bytestring insertion" $ do
let builders = replicate 10000 (lazyByteStringInsert "hello world!")
let lbs = toLazyByteString $ mconcat builders
let src = mconcat $ map (CL.sourceList . return) builders
outBss <- runConduit $ src .| builderToByteString .| CL.consume
lbs `shouldBe` L.fromChunks outBss
it "flush shouldn't bring in empty strings." $ do
let dat = ["hello", "world"]
src = CL.sourceList dat .| CL.map ((`mappend` flush) . byteString)
out <- runConduit $ src .| builderToByteString .| CL.consume
dat `shouldBe` out
prop "flushing" $ \bss' -> runST $ do
let bss = concatMap (\bs -> [Chunk $ S.pack bs, Flush]) $ filter (not . null) bss'
let chunks = map (fmap byteString) bss
let src = CL.sourceList chunks
outBss <- runConduit $ src .| builderToByteStringFlush .| CL.consume
if bss == outBss then return () else error (show (bss, outBss))
return $ bss == outBss
it "large flush input" $ do
let lbs = L.pack $ concat $ replicate 100000 [0..255]
let chunks = map (Chunk . byteString) (L.toChunks lbs)
let src = CL.sourceList chunks
bss <- runConduit $ src .| builderToByteStringFlush .| CL.consume
let unFlush (Chunk x) = [x]
unFlush Flush = []
L.fromChunks (concatMap unFlush bss) `shouldBe` lbs
|