File: ZlibSpec.hs

package info (click to toggle)
haskell-conduit-extra 1.3.8-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 288 kB
  • sloc: haskell: 2,601; makefile: 3
file content (92 lines) | stat: -rw-r--r-- 3,873 bytes parent folder | download | duplicates (5)
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
80
81
82
83
84
85
86
87
88
89
90
91
92
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE OverloadedStrings #-}
module Data.Conduit.ZlibSpec (spec) where

import Test.Hspec
import Test.Hspec.QuickCheck (prop)

import Data.Conduit ((.|), runConduit)
import qualified Data.Conduit as C
import qualified Data.Conduit.List as CL
import qualified Data.Conduit.Zlib as CZ
import qualified Data.ByteString as S
import qualified Data.ByteString.Lazy as L
import Data.ByteString.Char8 ()
import Data.ByteString.Lazy.Char8 ()
import Control.Monad (replicateM_)

spec :: Spec
spec = describe "Data.Conduit.Zlib" $ do
        prop "idempotent" $ \bss' -> do
            let bss = map S.pack bss'
                lbs = L.fromChunks bss
                src = mconcat $ map (CL.sourceList . return) bss
            outBss <- runConduit $ src .| CZ.gzip .| CZ.ungzip .| CL.consume
            L.fromChunks outBss `shouldBe` lbs
        prop "flush" $ \bss' -> do
            let bss = map S.pack $ filter (not . null) bss'
                bssC = concatMap (\bs -> [C.Chunk bs, C.Flush]) bss
                src = mconcat $ map (CL.sourceList . return) bssC
            outBssC <- runConduit
                     $ src
                    .| CZ.compressFlush 5 (CZ.WindowBits 31)
                    .| CZ.decompressFlush (CZ.WindowBits 31)
                    .| CL.consume
            outBssC `shouldBe` bssC
        it "compressFlush large data" $ do
            let content = L.pack $ map (fromIntegral . fromEnum) $ concat $ ["BEGIN"] ++ map show [1..100000 :: Int] ++ ["END"]
                src = CL.sourceList $ map C.Chunk $ L.toChunks content
            bssC <- runConduit $ src .| CZ.compressFlush 5 (CZ.WindowBits 31) .| CL.consume
            let unChunk (C.Chunk x) = [x]
                unChunk C.Flush = []
            bss <- runConduit $ CL.sourceList bssC .| CL.concatMap unChunk .| CZ.ungzip .| CL.consume
            L.fromChunks bss `shouldBe` content

        it "uncompressed after compressed" $ do
            let c = "This data is stored compressed."
                u = "This data isn't."
            let src1 = do
                    C.yield c .| CZ.gzip
                    C.yield u
            encoded <- runConduit $ src1 .| CL.consume
            let src2 = mapM_ C.yield encoded
            (c', u') <- runConduit $ src2 .| do
                c' <- CZ.ungzip .| CL.consume
                u' <- CL.consume
                return (S.concat c', S.concat u')
            c' `shouldBe` c
            u' `shouldBe` u

        it "multiple compressed values" $ do
            let s1 = "hello"
                s2 = "world"
                src = do
                    C.yield s1 .| CZ.gzip
                    C.yield s2 .| CZ.gzip
            actual <- runConduit $ src .| CZ.multiple CZ.ungzip .| CL.consume
            S.concat actual `shouldBe` S.concat [s1, s2]

        it "single compressed, multiple uncompressed chunks" $ do
            let s1 = "hello"
                s2 = "there"
                s3 = "world"
            s1Z <- fmap S.concat $ runConduit $ C.yield s1 .| CZ.gzip .| CL.consume
            let src = do
                    C.yield $ S.append s1Z s2
                    C.yield s3
            actual <- runConduit $ src .| do
                x <- fmap S.concat $ CZ.ungzip .| CL.consume
                y <- CL.consume
                return (x, y)
            actual `shouldBe` (s1, [s2, s3])

        it "multiple, over 32k" $ do
            let str = "One line"
                cnt = 30000
                src = replicateM_ cnt $ C.yield str .| CZ.gzip
            actual <- fmap S.concat $ runConduit $ src .| CZ.multiple CZ.ungzip .| CL.consume
            let expected = S.concat (replicate cnt str)
            S.length actual `shouldBe` S.length expected
            actual `shouldBe` expected