{-# LANGUAGE OverloadedStrings #-} module Main ( main ) where import Scanner import Prelude hiding (take, takeWhile) import Data.Either import qualified Data.ByteString as ByteString import qualified Data.ByteString.Lazy as Lazy.ByteString import Test.Hspec main :: IO () main = hspec $ do anyWord8Spec stringSpec takeSpec takeWhileSpec lookAheadSpec scanWithSpec anyWord8Spec :: Spec anyWord8Spec = describe "anyWord8" $ do it "should return the current byte" $ do let bs = ByteString.pack [42, 43] scanOnly anyWord8 bs `shouldBe` Right 42 it "should consume the current byte" $ do let bs = ByteString.pack [42, 43] scanOnly (anyWord8 *> anyWord8) bs `shouldBe` Right 43 let bs' = Lazy.ByteString.fromChunks [ ByteString.pack [42] , ByteString.pack [43] , ByteString.pack [44] ] scanLazy (anyWord8 *> anyWord8 *> anyWord8) bs' `shouldBe` Right 44 it "should ask for more input" $ do let bs = Lazy.ByteString.fromChunks [ ByteString.pack [42] , ByteString.pack [43] ] scanLazy (anyWord8 *> anyWord8) bs `shouldBe` Right 43 it "should fail on end of input" $ do let bs = ByteString.empty scanOnly anyWord8 bs `shouldSatisfy` isLeft stringSpec :: Spec stringSpec = describe "string" $ do it "should consume the string" $ do let bs = "hello world" scanOnly (string "hello" *> anyWord8) bs `shouldBe` Right 32 it "should ask for more input" $ do let bs = Lazy.ByteString.fromChunks [ "hel" , "lo" ] scanLazy (string "hello") bs `shouldBe` Right () it "should fail on wrong input" $ do let bs = "helo world" scanOnly (string "hello") bs `shouldSatisfy` isLeft takeSpec :: Spec takeSpec = describe "take" $ do it "should return the first n bytes" $ do let bs = "hello world" scanOnly (take 5) bs `shouldBe` Right "hello" it "should ask for more input" $ do let bs = Lazy.ByteString.fromChunks [ "he" , "l" , "lo world" ] scanLazy (take 5) bs `shouldBe` Right "hello" it "should fail on end of input" $ do let bs = "hell" scanOnly (take 5) bs `shouldSatisfy` isLeft let bs' = Lazy.ByteString.fromChunks [ "he" , "l" , "l" ] scanLazy (take 5) bs' `shouldSatisfy` isLeft takeWhileSpec :: Spec takeWhileSpec = describe "takeWhile" $ do it "should return bytes according to the predicate" $ do let bs = "hello world" scanOnly (takeWhile (/= 32)) bs `shouldBe` Right "hello" it "should ask for more input" $ do let bs = Lazy.ByteString.fromChunks [ "he" , "l" , "lo world" ] scanLazy (takeWhile (/= 32)) bs `shouldBe` Right "hello" it "should return everything is predicate where becomes False" $ do let bs = "hello" scanOnly (takeWhile (/= 32)) bs `shouldBe` Right "hello" lookAheadSpec :: Spec lookAheadSpec = describe "lookAhead" $ do it "should return the next byte" $ do let bs = ByteString.pack [42, 43] scanOnly lookAhead bs `shouldBe` Right (Just 42) it "should return Nothing on end of input" $ do let bs = ByteString.empty scanOnly lookAhead bs `shouldBe` Right Nothing it "should not consume input" $ do let bs = ByteString.pack [42, 43] scanOnly (lookAhead *> anyWord8) bs `shouldBe` Right 42 it "should ask for more input" $ do let bs = Lazy.ByteString.fromChunks [ ByteString.pack [42] , ByteString.pack [43] ] scanLazy (anyWord8 *> lookAhead) bs `shouldBe` Right (Just 43) scanWithSpec :: Spec scanWithSpec = describe "scanWith" $ do it "should apply the scanner" $ do let bs = ByteString.pack [42, 43] let Just (Scanner.Done _ r) = scanWith (Just ByteString.empty) anyWord8 bs r `shouldBe` 42 it "should resupply scanner when necessary" $ do let bs = "a" p = Scanner.anyChar8 *> Scanner.anyChar8 let Just (Scanner.Done _ r) = scanWith (Just "b") p bs r `shouldBe` 'b'