replace-attoparsec 1.4.5.0 → 1.5.0.0
raw patch · 7 files changed
+172/−274 lines, 7 filesdep +HUnitdep +hspecdep −Cabaldep ~attoparsecdep ~bytestringdep ~parsersPVP ok
version bump matches the API change (PVP)
Dependencies added: HUnit, hspec
Dependencies removed: Cabal
Dependency ranges changed: attoparsec, bytestring, parsers, text
API changes (from Hackage documentation)
Files
- CHANGELOG.md +10/−0
- README.md +16/−25
- replace-attoparsec.cabal +13/−27
- tests/TestByteString.hs +47/−88
- tests/TestText.hs +57/−99
- tests/TestTextLazy.hs +15/−35
- tests/Tests.hs +14/−0
CHANGELOG.md view
@@ -1,5 +1,15 @@ # Revision history for replace-attoparsec +## 1.5.0.0 -- 2023-05-30++Upgrade to GHC v9.4.4, text v2.0.1++Text does not work with GHC v9.4.3++Test+* exitcode-stdio-1.0 instead of detailed-0.9+* HSpec instead of Cabal Distribution.TestSuite+ ## 1.4.5.0 -- 2021-07-29 Add Replace.Attoparsec.Text.Lazy
README.md view
@@ -95,6 +95,7 @@ import Replace.Attoparsec.Text import Data.Attoparsec.Text as AT import qualified Data.Text as T+import Control.Applicative import Data.Either import Data.Char ```@@ -127,7 +128,7 @@ parens = do char '(' manyTill- (void (satisfy $ notInClass "()") <|> void parens)+ (void parens <|> void anyChar) (char ')') pure () @@ -328,30 +329,20 @@ See [replace-benchmark](https://github.com/jamesdbrock/replace-benchmark) for details. -| Program | dense | sparse |-| :--- | ---: | ---: |-| [Python 3.7.4 `re.sub`][sub] *repl* function | 89.23ms | 23.98ms |-| [Perl 5 `s///ge`][s] | 180.65ms | 5.02ms |-| [`Replace.Megaparsec.streamEdit`][m] `String` | 441.94ms | 375.04ms |-| [`Replace.Megaparsec.streamEdit`][m] `ByteString` | 529.99ms | 73.76ms |-| [`Replace.Megaparsec.streamEdit`][m] `Text` | 547.47ms | 139.21ms |-| [`Replace.Attoparsec.ByteString.streamEdit`][ab] | 394.12ms | 41.13ms |-| [`Replace.Attoparsec.Text.streamEdit`][at] | 515.26ms | 46.10ms |-| [`Text.Regex.Applicative.replace`][ra] `String` | 1083.98ms | 646.40ms |-| [`Text.Regex.PCRE.Heavy.gsub`][ph] `Text` | > 10min | 14.29ms |-| [`Control.Lens.Regex.ByteString.match`][lb] | > 10min | 4.27ms |-| [`Control.Lens.Regex.Text.match`][lt] | > 10min | 14.74ms |--[sub]: https://docs.python.org/3/library/re.html#re.sub-[s]: https://perldoc.perl.org/functions/s.html-[m]: https://hackage.haskell.org/package/replace-megaparsec/docs/Replace-Megaparsec.html#v:streamEdit-[ab]: https://hackage.haskell.org/package/replace-attoparsec/docs/Replace-Attoparsec-ByteString.html#v:streamEdit-[at]: https://hackage.haskell.org/package/replace-attoparsec/docs/Replace-Attoparsec-Text.html#v:streamEdit-[ra]: http://hackage.haskell.org/package/regex-applicative/docs/Text-Regex-Applicative.html#v:replace-[ss]: http://hackage.haskell.org/package/stringsearch/docs/Data-ByteString-Search.html#v:replace-[ph]: http://hackage.haskell.org/package/pcre-heavy/docs/Text-Regex-PCRE-Heavy.html#v:gsub-[lb]: https://hackage.haskell.org/package/lens-regex-pcre/docs/Control-Lens-Regex-ByteString.html#v:match-[lt]: https://hackage.haskell.org/package/lens-regex-pcre/docs/Control-Lens-Regex-Text.html#v:match+| Program | dense *ms* | sparse *ms* |+| :--- | ---: | ---: |+| Python 3.10.9 [`re.sub`](https://docs.python.org/3/library/re.html#re.sub) *repl* function | 557.22 | 35.47 |+| Perl v5.36.0 [`s///ge`](https://perldoc.perl.org/functions/s.html) function | 1208.66 | 12.61 |+| [`Replace.Megaparsec.streamEdit`](https://hackage.haskell.org/package/replace-megaparsec/docs/Replace-Megaparsec.html#v:streamEdit) `String` | 2921.25 | 2911.81 |+| [`Replace.Megaparsec.streamEdit`](https://hackage.haskell.org/package/replace-megaparsec/docs/Replace-Megaparsec.html#v:streamEdit) `ByteString` | 3743.25 | 757.21 |+| [`Replace.Megaparsec.streamEdit`](https://hackage.haskell.org/package/replace-megaparsec/docs/Replace-Megaparsec.html#v:streamEdit) `Text` | 3818.47 | 881.69 |+| [`Replace.Attoparsec.ByteString.streamEdit`](https://hackage.haskell.org/package/replace-attoparsec/docs/Replace-Attoparsec-ByteString.html#v:streamEdit) | 3006.38 | 179.66 |+| [`Replace.Attoparsec.Text.streamEdit`](https://hackage.haskell.org/package/replace-attoparsec/docs/Replace-Attoparsec-Text.html#v:streamEdit) | 3062.43 | 300.13 |+| [`Replace.Attoparsec.Text.Lazy.streamEdit`](https://hackage.haskell.org/package/replace-attoparsec/docs/Replace-Attoparsec-Text-Lazy.html#v:streamEdit) | 3102.15 | 241.58 |+| [`Text.Regex.Applicative.replace`](http://hackage.haskell.org/package/regex-applicative/docs/Text-Regex-Applicative.html#v:replace) `String` | 13875.25 | 4330.52 |+| [`Text.Regex.PCRE.Heavy.gsub`](http://hackage.haskell.org/package/pcre-heavy/docs/Text-Regex-PCRE-Heavy.html#v:gsub) `Text` | ∞ | 113.27 |+| [`Control.Lens.Regex.ByteString.match`](https://hackage.haskell.org/package/lens-regex-pcre/docs/Control-Lens-Regex-ByteString.html#v:match) | ∞ | 117.05 |+| [`Control.Lens.Regex.Text.match`](https://hackage.haskell.org/package/lens-regex-pcre/docs/Control-Lens-Regex-Text.html#v:match) | ∞ | 35.97 | # Hypothetically Asked Questions
replace-attoparsec.cabal view
@@ -1,7 +1,7 @@ name: replace-attoparsec-version: 1.4.5.0+version: 1.5.0.0 cabal-version: 1.18-synopsis: Find, replace, and split string patterns with Attoparsec parsers (instead of regex)+synopsis: Find, replace, split string patterns with Attoparsec parsers (instead of regex) homepage: https://github.com/jamesdbrock/replace-attoparsec bug-reports: https://github.com/jamesdbrock/replace-attoparsec/issues license: BSD2@@ -25,39 +25,25 @@ library hs-source-dirs: src build-depends: base >=4.0 && <5.0- , attoparsec- , bytestring- , text+ , attoparsec >=0.4 && <1.0+ , bytestring >=0.2 && <1.0+ , text >=0.2 && <3.0 default-language: Haskell2010 exposed-modules: Replace.Attoparsec.Text Replace.Attoparsec.Text.Lazy , Replace.Attoparsec.ByteString- ghc-options: -O2 -Wall -test-suite test-bytestring- type: detailed-0.9- test-module: TestByteString+test-suite tests+ type: exitcode-stdio-1.0+ main-is: Tests.hs+ other-modules: TestByteString TestText TestTextLazy hs-source-dirs: tests default-language: Haskell2010 build-depends: base >= 4.0 && < 5.0 , replace-attoparsec , attoparsec- , Cabal+ , hspec >=2.0.0 && <3.0.0+ , HUnit >=1.1 && <2.0 , bytestring- , parsers- ghc-options: -Wall--test-suite test-text- type: detailed-0.9- test-module: TestText- other-modules: TestTextLazy- hs-source-dirs: tests- default-language: Haskell2010- build-depends: base >= 4.0 && < 5.0- , replace-attoparsec- , attoparsec- , Cabal- , text- , parsers- ghc-options: -Wall-+ , text >=0.2 && <3.0+ , parsers >=0.1 && < 1.0
tests/TestByteString.hs view
@@ -2,10 +2,10 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE PackageImports #-} {-# LANGUAGE CPP #-}+{-# LANGUAGE BlockArguments #-} module TestByteString ( tests ) where -import Distribution.TestSuite as TestSuite import Data.Attoparsec.ByteString as A import Data.Attoparsec.Combinator import qualified Data.ByteString as B@@ -13,118 +13,77 @@ 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 :: IO [Test]-tests = return- [ Test $ runParserTest "findAllCap upperChar"+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.- , Test $ runParserTest "zero-consumption parser"+ runParserTest "zero-consumption parser" (sepCap (many upperChar)) ("aBcD" :: B.ByteString) [Left "a", Right [c2w 'B'], Left "c", Right [c2w 'D']]- , Test $ runParserTest "scinum"+ runParserTest "scinum" (sepCap scinum)- ("1E3")- ([Right (1,3)])- , Test $ runParserTest "monad fail"+ "1E3"+ [Right (1,3)]+ runParserTest "monad fail" (sepCap (fail "" :: Parser ()))- ("xxx")- ([Left "xxx"])+ "xxx"+ [Left "xxx"] #if MIN_VERSION_GLASGOW_HASKELL(8,6,0,0)- , Test $ runParserTest "read fail"+ runParserTest "read fail" (sepCap (return (read "a" :: Int) :: Parser Int)) ("a") ([Left "a"]) #endif- , Test $ runParserFeed "const string"+ runParserFeed "const string" (sepCap (string "aa"))- (" a") ("a ")- ([Left " ",Right"aa",Left" "])- , Test $ runParserTest "empty input" (sepCap (fail "" :: Parser ())) "" []- , Test $ streamEditTest "x to o" (string "x") (const "o") "x x x" "o o o"- , Test $ streamEditTest "x to o inner" (string "x") (const "o") " x x x " " o o o "- , Test $ streamEditTest "ordering" (string "456") (const "ABC") "123456789" "123ABC789"- , Test $ streamEditTest "empty input" (match (fail "")) (fst) "" ""- , Test $ breakCapTest "basic" upperChar "aAa" (Just ("a", c2w 'A', "a"))- , Test $ breakCapTest "first" upperChar "Aa" (Just ("", c2w 'A', "a"))- , Test $ breakCapTest "last" upperChar "aA" (Just ("a", c2w 'A', ""))- , Test $ breakCapTest "fail" upperChar "aaa" Nothing- , Test $ breakCapTest "match" (match upperChar) "aAa" (Just ("a", ("A",c2w 'A'), "a"))- , Test $ breakCapTest "zero-width" (lookAhead upperChar) "aAa" (Just ("a", c2w 'A', "Aa"))- , Test $ breakCapTest "empty input" upperChar "" Nothing- , Test $ breakCapTest "empty input zero-width" (return () :: Parser ()) "" (Just ("", (), ""))- ]+ " 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 = TestInstance- { run = do- case parseOnly p input of- Left e -> return (Finished $ TestSuite.Fail $ show e)- Right output ->- if (output == expected)- then return (Finished Pass)- else return (Finished $ TestSuite.Fail- $ "got " <> show output <> " expected " <> show expected)- , name = "parseOnly sepCap " <> nam- , tags = []- , options = []- , setOption = \_ _ -> Left "no options supported"- }+ runParserTest nam p input expected = it nam $ shouldBe+ (parseOnly p input) (Right expected) - runParserFeed nam p input1 input2 expected = TestInstance- { run = do- case parse p input1 of- A.Fail _i _ e -> return (Finished $ TestSuite.Fail $ show e)- A.Partial cont1 -> case cont1 input2 of- A.Fail _i _ e -> return (Finished $ TestSuite.Fail $ show e)- A.Partial cont2 -> case cont2 "" of- A.Fail _i _ e -> return (Finished $ TestSuite.Fail $ show e)- A.Partial _ -> return (Finished $ TestSuite.Fail $ "Should not ask for more input")- A.Done _i output ->- if (output == expected)- then return (Finished Pass)- else return (Finished $ TestSuite.Fail- $ "got " <> show output <> " expected " <> show expected)- A.Done _i _output -> return (Finished $ TestSuite.Fail $ "Should ask for more input")- A.Done _i _output -> return (Finished $ TestSuite.Fail $ "Should ask for more input")- , name = "parse Partial sepCap " <> nam- , tags = []- , options = []- , setOption = \_ _ -> Left "no options supported"- }+ 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 = TestInstance- { run = do- let output = streamEdit sep editor input- if (output == expected)- then return (Finished Pass)- else return (Finished $ TestSuite.Fail- $ show output ++ " ≠ " ++ show expected)- , name = "streamEdit " ++ nam- , tags = []- , options = []- , setOption = \_ _ -> Left "no options supported"- }+ streamEditTest nam sep editor input expected = it nam $ shouldBe+ (streamEdit sep editor input) expected - breakCapTest nam sep input expected = TestInstance- { run = do- let output = breakCap sep input- if (output == expected)- then return (Finished Pass)- else return (Finished $ TestSuite.Fail- $ "got " <> show output <> " expected " <> show expected)- , name = "breakCap " ++ nam- , tags = []- , options = []- , setOption = \_ _ -> Left "no options supported"- }+ breakCapTest nam sep input expected = it nam $ shouldBe+ (breakCap sep input) expected scinum :: Parser (Double, Integer) scinum = do
tests/TestText.hs view
@@ -1,10 +1,10 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE CPP #-}+{-# LANGUAGE BlockArguments #-} module TestText ( tests ) where -import Distribution.TestSuite as TestSuite import Replace.Attoparsec.Text import Data.Attoparsec.Text as A import Data.Attoparsec.Combinator@@ -13,128 +13,86 @@ import Control.Applicative import Data.Bifunctor import qualified TestTextLazy+import Test.Hspec (describe, shouldBe, it, SpecWith)+import Test.HUnit (assertFailure) findAllCap' :: Parser a -> Parser [Either T.Text (T.Text, a)] findAllCap' sep = sepCap (match sep) findAll' :: Parser b -> Parser [Either T.Text T.Text]-findAll' sep = (fmap.fmap) (second fst) $ sepCap (match sep)+findAll' sep = fmap (second fst) <$> sepCap (match sep) -tests :: IO [Test]-tests = liftA2 (<>)- (pure- [ Test $ runParserTest "findAllCap upperChar"+tests :: SpecWith ()+tests = describe "input Text" do+ runParserTest "findAllCap upperChar" (findAllCap' (upper :: Parser Char)) ("aBcD" :: T.Text) [Left "a", Right ("B", 'B'), Left "c", Right ("D", 'D')] -- check that sepCap can progress even when parser consumes nothing -- and succeeds.- , Test $ runParserTest "zero-consumption parser"+ runParserTest "zero-consumption parser" (sepCap (many (upper :: Parser Char))) ("aBcD" :: T.Text) [Left "a", Right "B", Left "c", Right "D"]- , Test $ runParserTest "scinum"+ runParserTest "scinum" (sepCap scinum)- ("1E3")- ([Right (1,3)])- , Test $ runParserTest "monad fail"+ "1E3"+ [Right (1,3)]+ runParserTest "monad fail" (sepCap (fail "" :: Parser ()))- ("xxx")- ([Left "xxx"])-#if MIN_VERSION_GLASGOW_HASKELL(8,6,0,0)- , Test $ runParserTest "read fail"+ "xxx"+ [Left "xxx"]++ runParserTest "read fail" (sepCap (return (read "a" :: Int) :: Parser Int))- ("a")- ([Left "a"])-#endif- , Test $ runParserTest "findAll astral"- (findAll' ((A.takeWhile (=='𝅘𝅥𝅯') :: Parser T.Text)))+ "a"+ [Left "a"]++ runParserTest "findAll astral"+ (findAll' (A.takeWhile (=='𝅘𝅥𝅯') :: Parser T.Text)) ("𝄞𝅘𝅥𝅘𝅥𝅘𝅥𝅘𝅥𝅘𝅥𝅯𝅘𝅥𝅯𝅘𝅥𝅯𝅘𝅥𝅯𝅘𝅥𝅘𝅥𝅘𝅥𝅘𝅥" :: T.Text) [Left "𝄞𝅘𝅥𝅘𝅥𝅘𝅥𝅘𝅥", Right "𝅘𝅥𝅯𝅘𝅥𝅯𝅘𝅥𝅯𝅘𝅥𝅯", Left "𝅘𝅥𝅘𝅥𝅘𝅥𝅘𝅥"]- , Test $ runParserFeed "const string"+ runParserFeed "const string" (sepCap (string "aa"))- (" a") ("a ")- ([Left " ",Right"aa",Left" "])- , Test $ runParserFeed "findAll astral"- (findAll' ((A.takeWhile (=='𝅘𝅥𝅯') :: Parser T.Text)))- ("𝄞𝅘𝅥𝅘𝅥𝅘𝅥𝅘𝅥𝅘𝅥𝅯𝅘𝅥𝅯") ("𝅘𝅥𝅯𝅘𝅥𝅯𝅘𝅥𝅘𝅥𝅘𝅥𝅘𝅥" :: T.Text)+ " a" "a "+ [Left " ",Right "aa",Left " "]+ runParserFeed "findAll astral"+ (findAll' (A.takeWhile (=='𝅘𝅥𝅯') :: Parser T.Text))+ "𝄞𝅘𝅥𝅘𝅥𝅘𝅥𝅘𝅥𝅘𝅥𝅯𝅘𝅥𝅯" ("𝅘𝅥𝅯𝅘𝅥𝅯𝅘𝅥𝅘𝅥𝅘𝅥𝅘𝅥" :: T.Text) [Left "𝄞𝅘𝅥𝅘𝅥𝅘𝅥𝅘𝅥", Right "𝅘𝅥𝅯𝅘𝅥𝅯𝅘𝅥𝅯𝅘𝅥𝅯", Left "𝅘𝅥𝅘𝅥𝅘𝅥𝅘𝅥"]- , Test $ runParserTest "empty input" (sepCap (fail "" :: Parser ())) "" []- , Test $ streamEditTest "x to o" (string "x") (const "o") "x x x" "o o o"- , Test $ streamEditTest "x to o inner" (string "x") (const "o") " x x x " " o o o "- , Test $ streamEditTest "ordering" (string "456") (const "ABC") "123456789" "123ABC789"- , Test $ streamEditTest "empty input" (match (fail "")) (fst) "" ""- , Test $ breakCapTest "basic" upper "aAa" (Just ("a", 'A', "a"))- , Test $ breakCapTest "first" upper "Aa" (Just ("", 'A', "a"))- , Test $ breakCapTest "last" upper "aA" (Just ("a", 'A', ""))- , Test $ breakCapTest "fail" upper "aaa" Nothing- , Test $ breakCapTest "match" (match upper) "aAa" (Just ("a", ("A",'A'), "a"))- , Test $ breakCapTest "zero-width" (lookAhead upper) "aAa" (Just ("a",'A', "Aa"))- , Test $ breakCapTest "empty input" upper "" Nothing- , Test $ breakCapTest "empty input zero-width" (return () :: Parser ()) "" (Just ("", (), ""))- ]) TestTextLazy.tests+ 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" upper "aAa" (Just ("a", 'A', "a"))+ breakCapTest "first" upper "Aa" (Just ("", 'A', "a"))+ breakCapTest "last" upper "aA" (Just ("a", 'A', ""))+ breakCapTest "fail" upper "aaa" Nothing+ breakCapTest "match" (match upper) "aAa" (Just ("a", ("A",'A'), "a"))+ breakCapTest "zero-width" (lookAhead upper) "aAa" (Just ("a",'A', "Aa"))+ breakCapTest "empty input" upper "" Nothing+ breakCapTest "empty input zero-width" (return () :: Parser ()) "" (Just ("", (), "")) where- runParserTest nam p input expected = TestInstance- { run = do- case parseOnly p input of- Left e -> return (Finished $ TestSuite.Fail $ show e)- Right output ->- if (output == expected)- then return (Finished Pass)- else return (Finished $ TestSuite.Fail- $ "got " <> show output <> " expected " <> show expected)- , name = "parseOnly sepCap " <> nam- , tags = []- , options = []- , setOption = \_ _ -> Left "no options supported"- }+ runParserTest nam p input expected = it nam $ shouldBe+ (parseOnly p input) (Right expected) - runParserFeed nam p input1 input2 expected = TestInstance- { run = do- case parse p input1 of- A.Fail _i _ e -> return (Finished $ TestSuite.Fail $ show e)- A.Partial cont1 -> case cont1 input2 of- A.Fail _i _ e -> return (Finished $ TestSuite.Fail $ show e)- A.Partial cont2 -> case cont2 "" of- A.Fail _i _ e -> return (Finished $ TestSuite.Fail $ show e)- A.Partial _ -> return (Finished $ TestSuite.Fail $ "Should not ask for more input")- A.Done _i output ->- if (output == expected)- then return (Finished Pass)- else return (Finished $ TestSuite.Fail- $ "got " <> show output <> " expected " <> show expected)- A.Done _i _output -> return (Finished $ TestSuite.Fail $ "Should ask for more input")- A.Done _i _output -> return (Finished $ TestSuite.Fail $ "Should ask for more input")- , name = "parse Partial sepCap " <> nam- , tags = []- , options = []- , setOption = \_ _ -> Left "no options supported"- }+ 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 = TestInstance- { run = do- let output = streamEdit sep editor input- if (output == expected)- then return (Finished Pass)- else return (Finished $ TestSuite.Fail- $ "got " <> show output <> " expected " <> show expected)- , name = "streamEdit " ++ nam- , tags = []- , options = []- , setOption = \_ _ -> Left "no options supported"- }+ streamEditTest nam sep editor input expected = it nam $ shouldBe+ (streamEdit sep editor input) expected - breakCapTest nam sep input expected = TestInstance- { run = do- let output = breakCap sep input- if (output == expected)- then return (Finished Pass)- else return (Finished $ TestSuite.Fail- $ "got " <> show output <> " expected " <> show expected)- , name = "breakCap " ++ nam- , tags = []- , options = []- , setOption = \_ _ -> Left "no options supported"- }+ breakCapTest nam sep input expected = it nam $ shouldBe+ (breakCap sep input) expected scinum :: Parser (Double, Integer) scinum = do
tests/TestTextLazy.hs view
@@ -1,49 +1,29 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE CPP #-}+{-# LANGUAGE BlockArguments #-} -- Basically a copy of TestText with tests for chunks and no tests for partial -- input module TestTextLazy ( tests ) where -import Distribution.TestSuite as TestSuite import Replace.Attoparsec.Text.Lazy import Data.Attoparsec.Text.Lazy as A import qualified Data.Text.Lazy as T+import Test.Hspec (describe, shouldBe, it, SpecWith) -tests :: IO [Test]-tests = return- [ Test $ streamEditTest "x to o" (string "x") (const "o") "x x x" "o o o"- , Test $ streamEditTest "x to o inner" (string "x") (const "o") " x x x " " o o o "- , Test $ streamEditTest "ordering" (string "456") (const "ABC") "123456789" "123ABC789"- , Test $ streamEditTest "empty input" (match (fail "")) fst "" ""- , Test $ chunkTest "all chunks are processed" (string "x") (const "y") ["x", "x", "x"] id "yyy"- , Test $ chunkTest "matches across chunks" (string "abcd") (const "y") ["ab", "cd", "ab", "cd"] id "yy"- , Test $ chunkTest "multiple matches in one chunks" (string "x") (const "y") ["xxx", "xx"] id "yyyyy"- ]+tests :: SpecWith ()+tests = describe "input Text.Lazy" do+ 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 "" ""+ chunkTest "all chunks are processed" (string "x") (const "y") ["x", "x", "x"] id "yyy"+ chunkTest "matches across chunks" (string "abcd") (const "y") ["ab", "cd", "ab", "cd"] id "yy"+ chunkTest "multiple matches in one chunks" (string "x") (const "y") ["xxx", "xx"] id "yyyyy" where- chunkTest nam sep editor input post expected = TestInstance- { run = do- let output = post $ streamEdit sep editor (T.fromChunks input)- if (output == expected)- then pure (Finished Pass)- else return (Finished $ TestSuite.Fail- $ "got " <> show (T.toChunks output) <> " expected " <> show (T.toChunks expected))- , name = "chunkTest " ++ nam- , tags = []- , options = []- , setOption = \_ _ -> Left "no options supported"- }+ chunkTest nam sep editor input post expected = it nam $ shouldBe+ (post $ streamEdit sep editor (T.fromChunks input)) expected - streamEditTest nam sep editor input expected = TestInstance- { run = do- let output = streamEdit sep editor input- if (output == expected)- then return (Finished Pass)- else return (Finished $ TestSuite.Fail- $ "got " <> show output <> " expected " <> show expected)- , name = "streamEdit " ++ nam- , tags = []- , options = []- , setOption = \_ _ -> Left "no options supported"- }+ streamEditTest nam sep editor input expected = it nam $ shouldBe+ (streamEdit sep editor input) expected
+ tests/Tests.hs view
@@ -0,0 +1,14 @@+{-# LANGUAGE BlockArguments #-}++module Main ( main ) where++import Test.Hspec+import TestByteString+import TestText+import TestTextLazy++main :: IO ()+main = hspec do+ TestByteString.tests+ TestText.tests+ TestTextLazy.tests