megaparsec-tests 7.0.5 → 8.0.0
raw patch · 14 files changed
+212/−151 lines, 14 filesdep ~QuickCheckdep ~basedep ~megaparsecsetup-changedPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: QuickCheck, base, megaparsec, mtl
API changes (from Hackage documentation)
- Test.Hspec.Megaparsec.AdHoc: instance Test.QuickCheck.Arbitrary.Arbitrary s => Test.QuickCheck.Arbitrary.Arbitrary (Text.Megaparsec.State.State s)
+ Test.Hspec.Megaparsec.AdHoc: instance Test.QuickCheck.Arbitrary.Arbitrary s => Test.QuickCheck.Arbitrary.Arbitrary (Text.Megaparsec.State.State s e)
- Test.Hspec.Megaparsec.AdHoc: grs' :: (forall m. MonadParsec Void String m => m a) -> String -> ((State String, Either (ParseErrorBundle String Void) a) -> Expectation) -> Expectation
+ Test.Hspec.Megaparsec.AdHoc: grs' :: (forall m. MonadParsec Void String m => m a) -> String -> ((State String Void, Either (ParseErrorBundle String Void) a) -> Expectation) -> Expectation
- Test.Hspec.Megaparsec.AdHoc: prs' :: Parser a -> String -> (State String, Either (ParseErrorBundle String Void) a)
+ Test.Hspec.Megaparsec.AdHoc: prs' :: Parser a -> String -> (State String Void, Either (ParseErrorBundle String Void) a)
Files
- LICENSE.md +1/−1
- README.md +7/−7
- Setup.hs +0/−4
- megaparsec-tests.cabal +10/−11
- src/Test/Hspec/Megaparsec/AdHoc.hs +6/−8
- tests/Text/Megaparsec/Byte/LexerSpec.hs +6/−2
- tests/Text/Megaparsec/ByteSpec.hs +6/−2
- tests/Text/Megaparsec/Char/LexerSpec.hs +4/−1
- tests/Text/Megaparsec/CharSpec.hs +5/−2
- tests/Text/Megaparsec/DebugSpec.hs +5/−1
- tests/Text/Megaparsec/ErrorSpec.hs +7/−14
- tests/Text/Megaparsec/PosSpec.hs +6/−1
- tests/Text/Megaparsec/StreamSpec.hs +17/−13
- tests/Text/MegaparsecSpec.hs +132/−84
LICENSE.md view
@@ -1,4 +1,4 @@-Copyright © 2015–2019 Megaparsec contributors+Copyright © 2015–present Megaparsec contributors All rights reserved.
README.md view
@@ -1,17 +1,17 @@ # Megaparsec tests -Megaparsec's test suite as a standalone package. The reason for separtion is-that we can avoid circular dependency on `hspec-megaparsec` and thus avoid-keeping copies of its source files in our test suite, as we had to do-before. Another benefit is that we can export some auxiliary functions in-`megaparsec-tests` which can be used by other test suites, for example in-the `parser-combinators-tests` package.+Megaparsec's test suite as a standalone package. The reason for the+separation is that we can avoid circular dependency on `hspec-megaparsec`+and thus avoid keeping copies of its source files in our test suite, as we+had to do before. Another benefit is that we can export some auxiliary+functions in `megaparsec-tests` which can be used by other test suites, for+example in the `parser-combinators-tests` package. Version of `megaparsec-tests` will be kept in sync with versions of `megaparsec` from now on. ## License -Copyright © 2015–2019 Megaparsec contributors+Copyright © 2015–present Megaparsec contributors Distributed under FreeBSD license.
Setup.hs view
@@ -1,6 +1,2 @@-module Main (main) where- import Distribution.Simple--main :: IO () main = defaultMain
megaparsec-tests.cabal view
@@ -1,7 +1,7 @@ name: megaparsec-tests-version: 7.0.5+version: 8.0.0 cabal-version: 1.18-tested-with: GHC==8.0.2, GHC==8.2.2, GHC==8.4.4, GHC==8.6.5+tested-with: GHC==8.4.4, GHC==8.6.5, GHC==8.8.1 license: BSD2 license-file: LICENSE.md author: Megaparsec contributors@@ -21,15 +21,15 @@ library hs-source-dirs: src- build-depends: QuickCheck >= 2.7 && < 2.13- , base >= 4.9 && < 5.0+ build-depends: QuickCheck >= 2.10 && < 2.14+ , base >= 4.11 && < 5.0 , bytestring >= 0.2 && < 0.11 , containers >= 0.5 && < 0.7 , hspec >= 2.0 && < 3.0 , hspec-expectations >= 0.8 && < 0.9 , hspec-megaparsec >= 2.0 && < 3.0- , megaparsec == 7.0.5- , mtl >= 2.0 && < 3.0+ , megaparsec == 8.0.0+ , mtl >= 2.2.2 && < 3.0 , text >= 0.2 && < 1.3 , transformers >= 0.4 && < 0.6 exposed-modules: Test.Hspec.Megaparsec.AdHoc@@ -38,7 +38,6 @@ -Wincomplete-record-updates -Wincomplete-uni-patterns -Wnoncanonical-monad-instances- -Wnoncanonical-monadfail-instances else ghc-options: -O2 -Wall default-language: Haskell2010@@ -60,17 +59,17 @@ , Text.Megaparsec.PosSpec , Text.Megaparsec.StreamSpec , Text.MegaparsecSpec- build-depends: QuickCheck >= 2.7 && < 2.13- , base >= 4.9 && < 5.0+ build-depends: QuickCheck >= 2.10 && < 2.14+ , base >= 4.11 && < 5.0 , bytestring >= 0.2 && < 0.11 , case-insensitive >= 1.2 && < 1.3 , containers >= 0.5 && < 0.7 , hspec >= 2.0 && < 3.0 , hspec-expectations >= 0.8 && < 0.9 , hspec-megaparsec >= 2.0 && < 3.0- , megaparsec == 7.0.5+ , megaparsec == 8.0.0 , megaparsec-tests- , mtl >= 2.0 && < 3.0+ , mtl >= 2.2.2 && < 3.0 , parser-combinators >= 1.0 && < 2.0 , scientific >= 0.3.1 && < 0.4 , text >= 0.2 && < 1.3
src/Test/Hspec/Megaparsec/AdHoc.hs view
@@ -1,6 +1,6 @@ -- | -- Module : Test.Hspec.Megaparsec.AdHoc--- Copyright : © 2019 Megaparsec contributors+-- Copyright : © 2019–present Megaparsec contributors -- License : FreeBSD -- -- Maintainer : Mark Karpov <markkarpov92@gmail.com>@@ -9,7 +9,6 @@ -- -- Ad-hoc helpers used in Megaparsec's test suite. -{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-}@@ -98,7 +97,7 @@ -- ^ Parser to run -> String -- ^ Input for the parser- -> (State String, Either (ParseErrorBundle String Void) a)+ -> (State String Void, Either (ParseErrorBundle String Void) a) -- ^ Result of parsing prs' p s = runParser' p (initialState s) @@ -141,7 +140,7 @@ grs' :: (forall m. MonadParsec Void String m => m a) -- ^ Parser to run -> String -- ^ Input for the parser- -> ((State String, Either (ParseErrorBundle String Void) a) -> Expectation)+ -> ((State String Void, Either (ParseErrorBundle String Void) a) -> Expectation) -- ^ How to check result of parsing -> Expectation grs' p s r = do@@ -217,7 +216,7 @@ strSourcePos :: Pos -> SourcePos -> String -> SourcePos strSourcePos tabWidth ipos input =- let (x, _, _) = reachOffset maxBound pstate in x+ let (_, pst') = reachOffset maxBound pstate in pstateSourcePos pst' where pstate = PosState { pstateInput = input@@ -298,7 +297,7 @@ <$> (getNonNegative <$> arbitrary) <*> (E.fromList <$> scaleDown arbitrary) ] -instance Arbitrary s => Arbitrary (State s) where+instance Arbitrary s => Arbitrary (State s e) where arbitrary = do input <- scaleDown arbitrary offset <- choose (1, 10000)@@ -310,6 +309,7 @@ { pstateInput = input , pstateOffset = offset }+ , stateParseErrors = [] } instance Arbitrary s => Arbitrary (PosState s) where@@ -332,7 +332,5 @@ instance Arbitrary BL.ByteString where arbitrary = BL.pack <$> arbitrary -#if MIN_VERSION_QuickCheck(2,10,0) instance Arbitrary a => Arbitrary (NonEmpty a) where arbitrary = NE.fromList <$> (arbitrary `suchThat` (not . null))-#endif
tests/Text/Megaparsec/Byte/LexerSpec.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} module Text.Megaparsec.Byte.LexerSpec (spec) where@@ -5,7 +6,6 @@ import Control.Applicative import Data.ByteString (ByteString) import Data.Char (intToDigit, toUpper)-import Data.Monoid ((<>)) import Data.Scientific (Scientific, fromFloatDigits) import Data.Void import Data.Word (Word8)@@ -19,6 +19,10 @@ import qualified Data.ByteString.Char8 as B8 import qualified Text.Megaparsec.Byte as B +#if !MIN_VERSION_base(4,13,0)+import Data.Semigroup ((<>))+#endif+ type Parser = Parsec Void ByteString spec :: Spec@@ -297,7 +301,7 @@ -- ^ Parser to run -> ByteString -- ^ Input for the parser- -> (State ByteString, Either (ParseErrorBundle ByteString Void) a)+ -> (State ByteString Void, Either (ParseErrorBundle ByteString Void) a) -- ^ Result of parsing prs' p s = runParser' p (initialState s)
tests/Text/Megaparsec/ByteSpec.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} module Text.Megaparsec.ByteSpec (spec) where@@ -6,7 +7,6 @@ import Data.ByteString (ByteString) import Data.Char import Data.Maybe (fromMaybe)-import Data.Semigroup ((<>)) import Data.Void import Data.Word (Word8) import Test.Hspec@@ -17,6 +17,10 @@ import Text.Megaparsec.Byte import qualified Data.ByteString as B +#if !MIN_VERSION_base(4,13,0)+import Data.Semigroup ((<>))+#endif+ type Parser = Parsec Void ByteString spec :: Spec@@ -209,7 +213,7 @@ -- ^ Parser to run -> ByteString -- ^ Input for the parser- -> (State ByteString, Either (ParseErrorBundle ByteString Void) a)+ -> (State ByteString Void, Either (ParseErrorBundle ByteString Void) a) -- ^ Result of parsing prs' p s = runParser' p (initialState s)
tests/Text/Megaparsec/Char/LexerSpec.hs view
@@ -10,7 +10,6 @@ import Data.Char hiding (ord) import Data.List (isInfixOf) import Data.Maybe-import Data.Monoid ((<>)) import Data.Scientific (Scientific, fromFloatDigits) import Data.Void (Void) import Numeric (showInt, showIntAtBase, showHex, showOct, showFFloatAlt)@@ -22,6 +21,10 @@ import Text.Megaparsec.Char.Lexer import qualified Data.CaseInsensitive as CI import qualified Text.Megaparsec.Char as C++#if !MIN_VERSION_base(4,13,0)+import Data.Semigroup ((<>))+#endif spec :: Spec spec = do
tests/Text/Megaparsec/CharSpec.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE CPP #-}+{-# LANGUAGE CPP #-} {-# OPTIONS -fno-warn-orphans #-} module Text.Megaparsec.CharSpec (spec) where@@ -6,7 +6,6 @@ import Control.Monad import Data.Char import Data.List (nub, partition, isPrefixOf)-import Data.Monoid ((<>)) import Test.Hspec import Test.Hspec.Megaparsec import Test.Hspec.Megaparsec.AdHoc@@ -14,6 +13,10 @@ import Text.Megaparsec import Text.Megaparsec.Char import qualified Data.CaseInsensitive as CI++#if !MIN_VERSION_base(4,13,0)+import Data.Semigroup ((<>))+#endif instance Arbitrary GeneralCategory where arbitrary = elements [minBound..maxBound]
tests/Text/Megaparsec/DebugSpec.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} module Text.Megaparsec.DebugSpec@@ -5,13 +6,16 @@ where import Control.Monad-import Data.Monoid ((<>)) import Test.Hspec import Test.Hspec.Megaparsec import Test.Hspec.Megaparsec.AdHoc import Text.Megaparsec import Text.Megaparsec.Char import Text.Megaparsec.Debug++#if !MIN_VERSION_base(4,13,0)+import Data.Semigroup ((<>))+#endif spec :: Spec spec = do
tests/Text/Megaparsec/ErrorSpec.hs view
@@ -13,11 +13,10 @@ import Test.Hspec.Megaparsec.AdHoc () import Test.QuickCheck import Text.Megaparsec-import qualified Data.Semigroup as S-import qualified Data.Set as E+import qualified Data.Set as E -#if !MIN_VERSION_base(4,11,0)-import Data.Monoid+#if !MIN_VERSION_base(4,13,0)+import Data.Semigroup ((<>)) #endif spec :: Spec@@ -26,7 +25,7 @@ describe "Semigroup instance of ParseError" $ it "associativity" $ property $ \x y z ->- (x S.<> y) S.<> z === (x S.<> (y S.<> z) :: PE)+ (x <> y) <> z === (x <> (y <> z) :: PE) describe "Monoid instance of ParseError" $ do it "left identity" $@@ -67,13 +66,7 @@ TrivialError pos us ps <> FancyError pos xs `shouldBe` (FancyError pos xs :: PE) - describe "errorOffset" $- it "returns error position" $- property $ \e ->- errorOffset e `shouldBe`- (case e :: PE of- TrivialError o _ _ -> o- FancyError o _ -> o)+ -- NOTE 'errorOffset' and 'setErrorOffset' are trivial. describe "attachSourcePos" $ it "attaches the positions correctly" $@@ -83,9 +76,9 @@ pst' = if null xs then pst- else snd $ reachOffsetNoLine (last xs) pst+ else reachOffsetNoLine (last xs) pst rs = f <$> xs- f x = (x, fst (reachOffsetNoLine x pst))+ f x = (x, pstateSourcePos (reachOffsetNoLine x pst)) attachSourcePos id (xs :: [Int]) pst `shouldBe` (rs, pst') describe "errorBundlePretty" $ do
tests/Text/Megaparsec/PosSpec.hs view
@@ -1,13 +1,18 @@+{-# LANGUAGE CPP #-}+ module Text.Megaparsec.PosSpec (spec) where import Control.Exception (evaluate) import Data.Function (on) import Data.List (isInfixOf)-import Data.Semigroup ((<>)) import Test.Hspec import Test.Hspec.Megaparsec.AdHoc () import Test.QuickCheck import Text.Megaparsec.Pos++#if !MIN_VERSION_base(4,13,0)+import Data.Semigroup ((<>))+#endif spec :: Spec spec = do
tests/Text/Megaparsec/StreamSpec.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-}@@ -9,7 +10,6 @@ import Data.List (foldl') import Data.List.NonEmpty (NonEmpty (..)) import Data.Proxy-import Data.Semigroup ((<>)) import Data.String (IsString) import Data.Word (Word8) import Test.Hspec@@ -22,6 +22,10 @@ import qualified Data.Text as T import qualified Data.Text.Lazy as TL +#if !MIN_VERSION_base(4,13,0)+import Data.Semigroup ((<>))+#endif+ spec :: Spec spec = do @@ -404,7 +408,7 @@ { pstateInput = "\n" :: s } o = pstateOffset pst + 1- (r, _, _) = reachOffset o pst+ r = pstateSourcePos . snd $ reachOffset o pst SourcePos n l _ = pstateSourcePos pst r `shouldBe` SourcePos n (l <> pos1) pos1 it "returns correct SourcePos (tab)" $@@ -413,7 +417,7 @@ { pstateInput = "\t" :: s } o = pstateOffset pst + 1- (r, _, _) = reachOffset o pst+ r = pstateSourcePos . snd $ reachOffset o pst SourcePos n l c = pstateSourcePos pst w = pstateTabWidth pst r `shouldBe` SourcePos n l (toNextTab w c)@@ -423,7 +427,7 @@ { pstateInput = "a" :: s } o = pstateOffset pst + 1- (r, _, _) = reachOffset o pst+ r = pstateSourcePos . snd $ reachOffset o pst SourcePos n l c = pstateSourcePos pst r `shouldBe` SourcePos n l (c <> pos1) it "replaces empty line with <empty line>" $@@ -432,7 +436,7 @@ { pstateInput = "" :: s , pstateLinePrefix = "" }- (_, r, _) = reachOffset o pst+ (r, _) = reachOffset o pst r `shouldBe` "<empty line>" it "replaces tabs with spaces in returned line" $ property $ \pst' -> do@@ -440,7 +444,7 @@ { pstateInput = "\ta\t" :: s , pstateLinePrefix = "\t" }- (_, r, _) = reachOffset 2 pst+ (r, _) = reachOffset 2 pst w = unPos (pstateTabWidth pst) r' = replicate (w * 2) ' ' ++ "a" ++ replicate w ' ' r `shouldBe` r'@@ -450,7 +454,7 @@ { pstateInput = "foo\nbar\nbaz" :: s , pstateLinePrefix = "123" }- (_, r, _) = reachOffset 0 pst+ (r, _) = reachOffset 0 pst r `shouldBe` "123foo" it "returns correct line (without line prefix)" $ property $ \pst' -> do@@ -458,7 +462,7 @@ { pstateInput = "foo\nbar\nbaz" :: s , pstateOffset = 0 }- (_, r, _) = reachOffset 4 pst+ (r, _) = reachOffset 4 pst r `shouldBe` "bar" it "works incrementally" $ property $ \os' (NonNegative d) s -> do@@ -469,7 +473,7 @@ [] -> d xs -> maximum xs + d f pst o =- let (_, _, pst') = reachOffset o pst+ let (_, pst') = reachOffset o pst in pst' reachOffset o' s `shouldBe` reachOffset o' s' @@ -491,7 +495,7 @@ { pstateInput = "\n" :: s } o = pstateOffset pst + 1- (r, _) = reachOffsetNoLine o pst+ r = pstateSourcePos (reachOffsetNoLine o pst) SourcePos n l _ = pstateSourcePos pst r `shouldBe` SourcePos n (l <> pos1) pos1 it "returns correct SourcePos (tab)" $@@ -500,7 +504,7 @@ { pstateInput = "\t" :: s } o = pstateOffset pst + 1- (r, _) = reachOffsetNoLine o pst+ r = pstateSourcePos (reachOffsetNoLine o pst) SourcePos n l c = pstateSourcePos pst w = pstateTabWidth pst r `shouldBe` SourcePos n l (toNextTab w c)@@ -510,7 +514,7 @@ { pstateInput = "a" :: s } o = pstateOffset pst + 1- (r, _) = reachOffsetNoLine o pst+ r = pstateSourcePos (reachOffsetNoLine o pst) SourcePos n l c = pstateSourcePos pst r `shouldBe` SourcePos n l (c <> pos1) it "works incrementally" $@@ -522,7 +526,7 @@ [] -> d xs -> maximum xs + d f pst o =- let (_, pst') = reachOffsetNoLine o pst+ let pst' = reachOffsetNoLine o pst in pst' reachOffsetNoLine o' s `shouldBe` reachOffsetNoLine o' s'
tests/Text/MegaparsecSpec.hs view
@@ -1,6 +1,6 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE Rank2Types #-}@@ -37,23 +37,17 @@ import qualified Control.Monad.Writer.Strict as S import qualified Data.ByteString as BS import qualified Data.List as DL-import qualified Data.Semigroup as G+import qualified Data.List.NonEmpty as NE import qualified Data.Set as E import qualified Data.Text as T -#if !MIN_VERSION_QuickCheck(2,8,2)-instance (Arbitrary a, Ord a) => Arbitrary (E.Set a) where- arbitrary = E.fromList <$> arbitrary- shrink = fmap E.fromList . shrink . E.toList-#endif- spec :: Spec spec = do describe "ParsecT Semigroup instance" $ it "the associative operation works" $ property $ \a b -> do- let p = pure [a] G.<> pure [b]+ let p = pure [a] <> pure [b] prs p "" `shouldParse` ([a,b] :: [Int]) describe "ParsecT Monoid instance" $ do@@ -416,19 +410,12 @@ describe "primitive combinators" $ do - describe "failure" $- it "signals correct parse error" $- property $ \us ps -> do- let p :: MonadParsec Void String m => m ()- p = void (failure us ps)- grs p "" (`shouldFailWith` TrivialError 0 us ps)-- describe "fancyFailure" $- it "singals correct parse error" $- property $ \xs -> do+ describe "parseError" $ do+ it "immediately fails with given parse error" $+ property $ \st e -> do let p :: MonadParsec Void String m => m ()- p = void (fancyFailure xs)- grs p "" (`shouldFailWith` FancyError 0 xs)+ p = parseError e+ runParser' p st `shouldBe` (st, Left (mkBundle st (nes e))) describe "label" $ do context "when inner parser succeeds consuming input" $ do@@ -1058,6 +1045,111 @@ grs p s (`shouldFailWith` pe) grs' p s (`failsLeaving` drop n s) + describe "signaling parse errors" $ do++ describe "failure" $+ it "signals correct parse error" $+ property $ \us ps -> do+ let p :: MonadParsec Void String m => m ()+ p = void (failure us ps)+ grs p "" (`shouldFailWith` TrivialError 0 us ps)++ describe "fancyFailure" $+ it "singals correct parse error" $+ property $ \xs -> do+ let p :: MonadParsec Void String m => m ()+ p = void (fancyFailure xs)+ grs p "" (`shouldFailWith` FancyError 0 xs)++ describe "unexpected" $+ it "signals correct parse error" $+ property $ \item -> do+ let p :: MonadParsec Void String m => m ()+ p = void (unexpected item)+ grs p "" (`shouldFailWith` TrivialError 0 (pure item) E.empty)++ describe "customFailure" $+ it "signals correct parse error" $+ property $ \n st -> do+ let p :: MonadParsec Int String m => m ()+ p = void (customFailure n)+ xs = E.singleton (ErrorCustom n)+ runParser p "" (stateInput st) `shouldFailWith` FancyError 0 xs+ runParser' p st `failsLeaving` stateInput st++ describe "region" $ do+ let f o' = \case+ TrivialError o us ps ->+ FancyError+ (max o o')+ (E.singleton . ErrorCustom $ maybe 0 (const 1) us + E.size ps)+ FancyError o xs ->+ FancyError+ (max o o')+ (E.singleton . ErrorCustom $ E.size xs)+ context "when inner parser succeeds" $ do+ it "delayed parse errors get updated correctly" $+ property $ \st es0 es1 es2 o' n -> do+ let p :: Parsec Int String Int+ p = do+ forM_ (NE.reverse es0) registerParseError+ region (f o') $+ forM_ (NE.reverse es1) registerParseError+ forM_ (NE.reverse es2) registerParseError+ return n+ es = es2 <> fmap (f o') es1 <> es0+ st' = st+ { stateParseErrors = NE.toList es+ }+ runParser' p st `shouldBe`+ ( st'+ , Left (mkBundle st es)+ )+ context "when inner parser fails" $ do+ it "delayed and normal parse errors get updated correctly" $+ property $ \st es0 es1 e o' -> do+ let p :: Parsec Int String ()+ p = do+ forM_ (NE.reverse es0) registerParseError+ region (f o') $ do+ forM_ (NE.reverse es1) registerParseError+ void (parseError e)+ es = fmap (f o') es1 <> es0+ st' = st+ { stateParseErrors = NE.toList es+ }+ runParser' p st `shouldBe`+ ( st'+ , Left (mkBundle st (nes (f o' e) <> es))+ )++ describe "registerParseError" $ do+ it "immediately fails with given parse error" $+ property $ \st es -> do+ let p :: MonadParsec Void String m => m ()+ p = forM_ (NE.reverse es) registerParseError+ st' = st+ { stateParseErrors = NE.toList es+ }+ runParser' p st `shouldBe`+ ( st'+ , Left (mkBundle st es)+ )++ describe "registerFailure" $+ it "signals correct parse error" $+ property $ \us ps -> do+ let p :: MonadParsec Void String m => m ()+ p = void (registerFailure us ps)+ grs p "" (`shouldFailWith` TrivialError 0 us ps)++ describe "reisterFancyFailure" $+ it "singals correct parse error" $+ property $ \xs -> do+ let p :: MonadParsec Void String m => m ()+ p = void (registerFancyFailure xs)+ grs p "" (`shouldFailWith` FancyError 0 xs)+ describe "derivatives from primitive combinators" $ do -- NOTE 'single' is tested via 'char' in "Text.Megaparsec.Char" and@@ -1139,22 +1231,6 @@ -- NOTE 'chunk' is tested via 'string' in "Text.Megaparsec.Char" and -- "Text.Megaparsec.Byte". - describe "unexpected" $- it "signals correct parse error" $- property $ \item -> do- let p :: MonadParsec Void String m => m ()- p = void (unexpected item)- grs p "" (`shouldFailWith` TrivialError 0 (pure item) E.empty)-- describe "customFailure" $- it "signals correct parse error" $- property $ \n st -> do- let p :: MonadParsec Int String m => m ()- p = void (customFailure n)- xs = E.singleton (ErrorCustom n)- runParser p "" (stateInput st) `shouldFailWith` FancyError 0 xs- runParser' p st `failsLeaving` stateInput st- describe "match" $ it "return consumed tokens along with the result" $ property $ \str -> do@@ -1162,40 +1238,6 @@ prs p str `shouldParse` (str,str) prs' p str `succeedsLeaving` "" - describe "region" $ do- context "when inner parser succeeds" $- it "has no effect" $- property $ \st e n -> do- let p :: Parser Int- p = region (const e) (pure n)- runParser' p st `shouldBe` (st, Right (n :: Int))- context "when inner parser fails" $- it "the given function is used on the parse error" $- property $ \st' e o' -> do- let p :: Parsec Int String Int- p = region f $- case e :: ParseError String Int of- TrivialError _ us ps -> failure us ps- FancyError _ xs -> fancyFailure xs- f (TrivialError o us ps) = FancyError- (max o o')- (E.singleton . ErrorCustom $ maybe 0 (const 1) us + E.size ps)- f (FancyError o xs) = FancyError- (max o o')- (E.singleton . ErrorCustom $ E.size xs)- r = FancyError- (max (errorOffset e) o')- (E.singleton . ErrorCustom $- case e of- TrivialError _ us ps -> maybe 0 (const 1) us + E.size ps- FancyError _ xs -> E.size xs )- finalOffset = max (errorOffset e) o'- st = st' { stateOffset = errorOffset e }- runParser' p st `shouldBe`- ( st { stateOffset = finalOffset }- , Left (mkBundle st r)- )- describe "takeRest" $ it "returns rest of the input" $ property $ \st@State {..} -> do@@ -1247,7 +1289,8 @@ property $ \st -> do let p :: Parser SourcePos p = getSourcePos- (spos, _, pst') = reachOffset (stateOffset st) (statePosState st)+ pst' = snd $ reachOffset (stateOffset st) (statePosState st)+ spos = pstateSourcePos pst' runParser' p st `shouldBe` (st { statePosState = pst' }, Right spos) describe "setOffset and getOffset" $@@ -1259,14 +1302,15 @@ describe "setParserState and getParserState" $ it "sets parser state and gets it back" $ property $ \s1 s2 -> do- let p :: MonadParsec Void String m => m (State String)+ let p :: MonadParsec Void String m => m (State String Void) p = do st <- getParserState guard (st == initialState s) setParserState s1 updateParserState (f s2) getParserState <* setInput ""- f (State s1' o pst) (State s2' _ _) = State (max s1' s2') o pst+ f (State s1' o pst de1) (State s2' _ _ de2) =+ State (max s1' s2') o pst (de1 <> de2) s = "" grs p s (`shouldParse` f s2 s1) @@ -1621,15 +1665,16 @@ showErrorComponent = show emulateStrParsing- :: State String+ :: State String Void -> String- -> (State String, Either (ParseErrorBundle String Void) String)-emulateStrParsing st@(State i o pst) s =+ -> (State String Void, Either (ParseErrorBundle String Void) String)+emulateStrParsing st@(State i o pst de) s = if s == take l i- then ( State (drop l i) (o + l) pst- , Right s )+ then ( State (drop l i) (o + l) pst de+ , Right s+ ) else ( st- , Left (mkBundle st (err o (etoks s <> utoks (take l i))))+ , Left (mkBundle st (nes (err o (etoks s <> utoks (take l i))))) ) where l = length s@@ -1641,11 +1686,14 @@ -> Bool eqParser p1 p2 s = runParser p1 "" s == runParser p2 "" s -mkBundle :: State s -> ParseError s e -> ParseErrorBundle s e-mkBundle s e = ParseErrorBundle- { bundleErrors = e :| []+mkBundle+ :: State s e+ -> NonEmpty (ParseError s e) -- FIXME change back if we don't use it+ -> ParseErrorBundle s e+mkBundle s es = ParseErrorBundle+ { bundleErrors = NE.sortWith errorOffset es , bundlePosState = statePosState s } -grabTabWidth :: (State a, b) -> Pos+grabTabWidth :: (State a e, b) -> Pos grabTabWidth = pstateTabWidth . statePosState . fst