Blame test/Data/Conduit/AttoparsecSpec.hs

Packit 4b2029
{-# LANGUAGE CPP               #-}
Packit 4b2029
{-# LANGUAGE OverloadedStrings #-}
Packit 4b2029
{-# LANGUAGE TupleSections     #-}
Packit 4b2029
{-# OPTIONS_GHC -fno-warn-incomplete-patterns #-}
Packit 4b2029
module Data.Conduit.AttoparsecSpec (spec) where
Packit 4b2029
import           Control.Exception                (fromException)
Packit 4b2029
import           Test.Hspec
Packit 4b2029
Packit 4b2029
import           Control.Applicative              ((<*), (<|>))
Packit 4b2029
import           Control.Monad
Packit 4b2029
import           Control.Monad.Trans.Resource (runExceptionT)
Packit 4b2029
import qualified Data.Attoparsec.ByteString.Char8
Packit 4b2029
import qualified Data.Attoparsec.Text
Packit 4b2029
import           Data.Conduit
Packit 4b2029
import           Data.Conduit.Attoparsec
Packit 4b2029
import qualified Data.Conduit.List                as CL
Packit 4b2029
Packit 4b2029
spec :: Spec
Packit 4b2029
spec = describe "Data.Conduit.AttoparsecSpec" $ do
Packit 4b2029
    describe "error position" $ do
Packit 4b2029
        it "works for text" $ do
Packit 4b2029
            let input = ["aaa\na", "aaa\n\n", "aaa", "aab\n\naaaa"]
Packit 4b2029
                badLine = 4
Packit 4b2029
                badCol = 6
Packit 4b2029
                badOff = 15
Packit 4b2029
                parser = Data.Attoparsec.Text.endOfInput <|> (Data.Attoparsec.Text.notChar 'b' >> parser)
Packit 4b2029
                sink = sinkParser parser
Packit 4b2029
                sink' = sinkParserEither parser
Packit 4b2029
            ea <- runExceptionT $ CL.sourceList input $$ sink
Packit 4b2029
            case ea of
Packit 4b2029
                Left e ->
Packit 4b2029
                    case fromException e of
Packit 4b2029
                        Just pe -> do
Packit 4b2029
                            errorPosition pe `shouldBe` Position badLine badCol badOff
Packit 4b2029
            ea' <- CL.sourceList input $$ sink'
Packit 4b2029
            case ea' of
Packit 4b2029
                Left pe ->
Packit 4b2029
                    errorPosition pe `shouldBe` Position badLine badCol badOff
Packit 4b2029
        it "works for bytestring" $ do
Packit 4b2029
            let input = ["aaa\na", "aaa\n\n", "aaa", "aab\n\naaaa"]
Packit 4b2029
                badLine = 4
Packit 4b2029
                badCol = 6
Packit 4b2029
                badOff = 15
Packit 4b2029
                parser = Data.Attoparsec.ByteString.Char8.endOfInput <|> (Data.Attoparsec.ByteString.Char8.notChar 'b' >> parser)
Packit 4b2029
                sink = sinkParser parser
Packit 4b2029
                sink' = sinkParserEither parser
Packit 4b2029
            ea <- runExceptionT $ CL.sourceList input $$ sink
Packit 4b2029
            case ea of
Packit 4b2029
                Left e ->
Packit 4b2029
                    case fromException e of
Packit 4b2029
                        Just pe -> do
Packit 4b2029
                            errorPosition pe `shouldBe` Position badLine badCol badOff
Packit 4b2029
            ea' <- CL.sourceList input $$ sink'
Packit 4b2029
            case ea' of
Packit 4b2029
                Left pe ->
Packit 4b2029
                    errorPosition pe `shouldBe` Position badLine badCol badOff
Packit 4b2029
        it "works in last chunk" $ do
Packit 4b2029
            let input = ["aaa\na", "aaa\n\n", "aaa", "aab\n\naaaa"]
Packit 4b2029
                badLine = 6
Packit 4b2029
                badCol = 5
Packit 4b2029
                badOff = 22
Packit 4b2029
                parser = Data.Attoparsec.Text.char 'c' <|> (Data.Attoparsec.Text.anyChar >> parser)
Packit 4b2029
                sink = sinkParser parser
Packit 4b2029
                sink' = sinkParserEither parser
Packit 4b2029
            ea <- runExceptionT $ CL.sourceList input $$ sink
Packit 4b2029
            case ea of
Packit 4b2029
                Left e ->
Packit 4b2029
                    case fromException e of
Packit 4b2029
                        Just pe -> do
Packit 4b2029
                            errorPosition pe `shouldBe` Position badLine badCol badOff
Packit 4b2029
            ea' <- CL.sourceList input $$ sink'
Packit 4b2029
            case ea' of
Packit 4b2029
                Left pe ->
Packit 4b2029
                    errorPosition pe `shouldBe` Position badLine badCol badOff
Packit 4b2029
        it "works in last chunk" $ do
Packit 4b2029
            let input = ["aaa\na", "aaa\n\n", "aaa", "aa\n\naaaab"]
Packit 4b2029
                badLine = 6
Packit 4b2029
                badCol = 6
Packit 4b2029
                badOff = 22
Packit 4b2029
                parser = Data.Attoparsec.Text.string "bc" <|> (Data.Attoparsec.Text.anyChar >> parser)
Packit 4b2029
                sink = sinkParser parser
Packit 4b2029
                sink' = sinkParserEither parser
Packit 4b2029
            ea <- runExceptionT $ CL.sourceList input $$ sink
Packit 4b2029
            case ea of
Packit 4b2029
                Left e ->
Packit 4b2029
                    case fromException e of
Packit 4b2029
                        Just pe -> do
Packit 4b2029
                            errorPosition pe `shouldBe` Position badLine badCol badOff
Packit 4b2029
            ea' <- CL.sourceList input $$ sink'
Packit 4b2029
            case ea' of
Packit 4b2029
                Left pe ->
Packit 4b2029
                    errorPosition pe `shouldBe` Position badLine badCol badOff
Packit 4b2029
        it "works after new line in text" $ do
Packit 4b2029
            let input = ["aaa\n", "aaa\n\n", "aaa", "aa\nb\naaaa"]
Packit 4b2029
                badLine = 5
Packit 4b2029
                badCol = 1
Packit 4b2029
                badOff = 15
Packit 4b2029
                parser = Data.Attoparsec.Text.endOfInput <|> (Data.Attoparsec.Text.notChar 'b' >> parser)
Packit 4b2029
                sink = sinkParser parser
Packit 4b2029
                sink' = sinkParserEither parser
Packit 4b2029
            ea <- runExceptionT $ CL.sourceList input $$ sink
Packit 4b2029
            case ea of
Packit 4b2029
                Left e ->
Packit 4b2029
                    case fromException e of
Packit 4b2029
                        Just pe -> do
Packit 4b2029
                            errorPosition pe `shouldBe` Position badLine badCol badOff
Packit 4b2029
            ea' <- CL.sourceList input $$ sink'
Packit 4b2029
            case ea' of
Packit 4b2029
                Left pe ->
Packit 4b2029
                    errorPosition pe `shouldBe` Position badLine badCol badOff
Packit 4b2029
        it "works after new line in bytestring" $ do
Packit 4b2029
            let input = ["aaa\n", "aaa\n\n", "aaa", "aa\nb\naaaa"]
Packit 4b2029
                badLine = 5
Packit 4b2029
                badCol = 1
Packit 4b2029
                badOff = 15
Packit 4b2029
                parser = Data.Attoparsec.ByteString.Char8.endOfInput <|> (Data.Attoparsec.ByteString.Char8.notChar 'b' >> parser)
Packit 4b2029
                sink = sinkParser parser
Packit 4b2029
                sink' = sinkParserEither parser
Packit 4b2029
            ea <- runExceptionT $ CL.sourceList input $$ sink
Packit 4b2029
            case ea of
Packit 4b2029
                Left e ->
Packit 4b2029
                    case fromException e of
Packit 4b2029
                        Just pe -> do
Packit 4b2029
                            errorPosition pe `shouldBe` Position badLine badCol badOff
Packit 4b2029
            ea' <- CL.sourceList input $$ sink'
Packit 4b2029
            case ea' of
Packit 4b2029
                Left pe ->
Packit 4b2029
                    errorPosition pe `shouldBe` Position badLine badCol badOff
Packit 4b2029
        it "works for first line" $ do
Packit 4b2029
            let input = ["aab\na", "aaa\n\n", "aaa", "aab\n\naaaa"]
Packit 4b2029
                badLine = 1
Packit 4b2029
                badCol = 3
Packit 4b2029
                badOff = 2
Packit 4b2029
                parser = Data.Attoparsec.Text.endOfInput <|> (Data.Attoparsec.Text.notChar 'b' >> parser)
Packit 4b2029
                sink = sinkParser parser
Packit 4b2029
                sink' = sinkParserEither parser
Packit 4b2029
            ea <- runExceptionT $ CL.sourceList input $$ sink
Packit 4b2029
            case ea of
Packit 4b2029
                Left e ->
Packit 4b2029
                    case fromException e of
Packit 4b2029
                        Just pe -> do
Packit 4b2029
                            errorPosition pe `shouldBe` Position badLine badCol badOff
Packit 4b2029
            ea' <- CL.sourceList input $$ sink'
Packit 4b2029
            case ea' of
Packit 4b2029
                Left pe ->
Packit 4b2029
                    errorPosition pe `shouldBe` Position badLine badCol badOff
Packit 4b2029
Packit 4b2029
    describe "conduitParser" $ do
Packit 4b2029
        it "parses a repeated stream" $ do
Packit 4b2029
            let input = ["aaa\n", "aaa\naaa\n", "aaa\n"]
Packit 4b2029
                parser = Data.Attoparsec.Text.string "aaa" <* Data.Attoparsec.Text.endOfLine
Packit 4b2029
                sink = conduitParserEither parser =$= CL.consume
Packit 4b2029
            (Right ea) <- runExceptionT $ CL.sourceList input $$ sink
Packit 4b2029
            let chk a = case a of
Packit 4b2029
                          Left{} -> False
Packit 4b2029
                          Right (_, xs) -> xs == "aaa"
Packit 4b2029
                chkp l = PositionRange (Position l 1 ((l - 1) * 4)) (Position (l+1) 1 (l * 4))
Packit 4b2029
            forM_ ea $ \ a -> a `shouldSatisfy` chk :: Expectation
Packit 4b2029
            forM_ (zip ea [1..]) $ \ (Right (pos, _), l) -> pos `shouldBe` chkp l
Packit 4b2029
            length ea `shouldBe` 4
Packit 4b2029
Packit 4b2029
        it "positions on first line" $ do
Packit 4b2029
            results <- yield "hihihi\nhihi"
Packit 4b2029
                $$ conduitParser (Data.Attoparsec.Text.string "\n" <|> Data.Attoparsec.Text.string "hi")
Packit 4b2029
                =$ CL.consume
Packit 4b2029
            let f (a, b, c, d, e, f, g) = (PositionRange (Position a b c) (Position d e f), g)
Packit 4b2029
            results `shouldBe` map f
Packit 4b2029
                [ (1, 1, 0, 1, 3, 2, "hi")
Packit 4b2029
                , (1, 3, 2, 1, 5, 4, "hi")
Packit 4b2029
                , (1, 5, 4, 1, 7, 6, "hi")
Packit 4b2029
Packit 4b2029
                , (1, 7, 6, 2, 1, 7, "\n")
Packit 4b2029
Packit 4b2029
                , (2, 1, 7, 2, 3, 9, "hi")
Packit 4b2029
                , (2, 3, 9, 2, 5, 11, "hi")
Packit 4b2029
                ]