{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE PackageImports #-} {-# LANGUAGE CPP #-} {-# LANGUAGE BlockArguments #-} module TestByteString ( tests ) where import Data.Attoparsec.ByteString as A import Data.Attoparsec.Combinator import qualified Data.ByteString as B import Data.ByteString.Internal (c2w) import "parsers" Text.Parser.Token import Replace.Attoparsec.ByteString import Control.Applicative import Test.Hspec (describe, shouldBe, it, SpecWith) import Test.HUnit (assertFailure) findAllCap' :: Parser a -> Parser [Either B.ByteString (B.ByteString, a)] findAllCap' sep = sepCap (match sep) tests :: SpecWith () tests = describe "input ByteString" do runParserTest "findAllCap upperChar" (findAllCap' upperChar) ("aBcD" :: B.ByteString) [Left "a", Right ("B", c2w 'B'), Left "c", Right ("D", c2w 'D')] -- check that sepCap can progress even when parser consumes nothing -- and succeeds. runParserTest "zero-consumption parser" (sepCap (many upperChar)) ("aBcD" :: B.ByteString) [Left "a", Right [c2w 'B'], Left "c", Right [c2w 'D']] runParserTest "scinum" (sepCap scinum) "1E3" [Right (1,3)] runParserTest "monad fail" (sepCap (fail "" :: Parser ())) "xxx" [Left "xxx"] #if MIN_VERSION_GLASGOW_HASKELL(8,6,0,0) runParserTest "read fail" (sepCap (return (read "a" :: Int) :: Parser Int)) ("a") ([Left "a"]) #endif runParserFeed "const string" (sepCap (string "aa")) " a" "a " [Left " ",Right"aa",Left" "] runParserTest "empty input" (sepCap (fail "" :: Parser ())) "" [] streamEditTest "x to o" (string "x") (const "o") "x x x" "o o o" streamEditTest "x to o inner" (string "x") (const "o") " x x x " " o o o " streamEditTest "ordering" (string "456") (const "ABC") "123456789" "123ABC789" streamEditTest "empty input" (match (fail "")) fst "" "" breakCapTest "basic" upperChar "aAa" (Just ("a", c2w 'A', "a")) breakCapTest "first" upperChar "Aa" (Just ("", c2w 'A', "a")) breakCapTest "last" upperChar "aA" (Just ("a", c2w 'A', "")) breakCapTest "fail" upperChar "aaa" Nothing breakCapTest "match" (match upperChar) "aAa" (Just ("a", ("A",c2w 'A'), "a")) breakCapTest "zero-width" (lookAhead upperChar) "aAa" (Just ("a", c2w 'A', "Aa")) breakCapTest "empty input" upperChar "" Nothing breakCapTest "empty input zero-width" (return () :: Parser ()) "" (Just ("", (), "")) where runParserTest nam p input expected = it nam $ shouldBe (parseOnly p input) (Right expected) runParserFeed nam p input1 input2 expected = it nam do case parse p input1 of A.Fail _i _ e -> assertFailure $ show e A.Partial cont1 -> case cont1 input2 of A.Fail _i _ e -> assertFailure $ show e A.Partial cont2 -> case cont2 "" of A.Fail _i _ e -> assertFailure $ show e A.Partial _ -> assertFailure "Should not ask for more input" A.Done _i output -> output `shouldBe` expected A.Done _i _output -> assertFailure "Should ask for more input" A.Done _i _output -> assertFailure "Should ask for more input" streamEditTest nam sep editor input expected = it nam $ shouldBe (streamEdit sep editor input) expected breakCapTest nam sep input expected = it nam $ shouldBe (breakCap sep input) expected scinum :: Parser (Double, Integer) scinum = do m <- (fromIntegral :: Integer -> Double) <$> decimal _ <- string "E" e <- decimal return (m, e) upperChar = satisfy $ \c -> c >= c2w 'A' && c <= c2w 'Z'