1module Data.Conduit.ExtraSpec where
2
3import Data.Conduit
4import Test.Hspec
5import Test.Hspec.QuickCheck
6import Data.Conduit.List (isolate, peek, consume)
7import qualified Data.Conduit.List as CL
8import qualified Data.Text as T
9import qualified Data.Text.Encoding as T
10import qualified Data.ByteString as S
11import qualified Data.Conduit.Text as CT
12
13spec :: Spec
14spec = describe "Data.Conduit.Extra" $ do
15    it "basic test" $ do
16        let sink2 :: ConduitT a o IO (Maybe a, Maybe a)
17            sink2 = do
18                ma1 <- fuseLeftovers id (isolate 10) peek
19                ma2 <- peek
20                return (ma1, ma2)
21
22            source = yield 1 >> yield 2
23        res <- runConduit $ source .| sink2
24        res `shouldBe` (Just 1, Just (1 :: Int))
25
26    it "get leftovers" $ do
27        let sink2 :: ConduitT a o IO ([a], [a], [a])
28            sink2 = do
29                (x, y) <- fuseReturnLeftovers (isolate 2) peek3
30                z <- CL.consume
31                return (x, y, z)
32
33            peek3 = do
34                x <- CL.take 3
35                mapM_ leftover $ reverse x
36                return x
37
38            source = mapM_ yield [1..5 :: Int]
39        res <- runConduit $ source .| sink2
40        res `shouldBe` ([1..2], [1..2], [3..5])
41
42    it "multiple values" $ do
43        let sink2 :: ConduitT a o IO ([a], Maybe a)
44            sink2 = do
45                ma1 <- fuseLeftovers id (isolate 10) peek3
46                ma2 <- peek
47                return (ma1, ma2)
48
49            peek3 = do
50                x <- CL.take 3
51                mapM_ leftover $ reverse x
52                return x
53
54            source = mapM_ yield [1..5]
55        res <- runConduit $ source .| sink2
56        res `shouldBe` ([1..3], Just (1 :: Int))
57
58    prop "more complex" $ \ss cnt -> do
59        let ts = map T.pack ss
60            src = mapM_ (yield . T.encodeUtf8) ts
61            conduit = CL.map T.decodeUtf8
62            sink = CT.take cnt .| consume
63            undo = return . T.encodeUtf8 . T.concat
64        res <- runConduit $ src .| do
65            x <- fuseLeftovers undo conduit sink
66            y <- consume
67            return (T.concat x, T.decodeUtf8 $ S.concat y)
68        res `shouldBe` T.splitAt cnt (T.concat ts)
69
70main :: IO ()
71main = hspec spec
72