indentation 0.2.0.2 → 0.2.0.3
raw patch · 5 files changed
+238/−1 lines, 5 filesdep +indentationdep +tastydep +tasty-hunitdep ~basedep ~parsecdep ~trifectaPVP ok
version bump matches the API change (PVP)
Dependencies added: indentation, tasty, tasty-hunit
Dependency ranges changed: base, parsec, trifecta
API changes (from Hackage documentation)
Files
- CHANGELOG.md +4/−0
- indentation.cabal +29/−1
- tests/ParensParsec.hs +86/−0
- tests/ParensTrifecta.hs +92/−0
- tests/all-tests.hs +27/−0
CHANGELOG.md view
@@ -1,3 +1,7 @@+# 0.2.0.3 #++* Add (simple) tests for Parsec and Trifecta.+ # 0.2.0.2 # * Allow building with `parsec >= 3.1.7` and `trifecta >= 1.5`
indentation.cabal view
@@ -1,5 +1,5 @@ name: indentation-version: 0.2.0.2+version: 0.2.0.3 synopsis: Indentation sensitive parsing combinators for Parsec and Trifecta description: Indentation sensitive parsing combinators for Parsec and Trifecta. . @@ -49,6 +49,34 @@ default-language: Haskell2010 ghc-options: -Wall++test-suite test-indentation+ default-language:+ Haskell2010+ type:+ exitcode-stdio-1.0+ hs-source-dirs:+ tests+ main-is: all-tests.hs+ if flag(Parsec) {+ cpp-options: -DENABLE_PARSEC_TESTS+ build-depends:+ parsec+ other-modules:+ ParensParsec+ }+ if flag(Parsec) {+ cpp-options: -DENABLE_TRIFECTA_TESTS+ build-depends:+ trifecta+ other-modules:+ ParensTrifecta+ }+ build-depends:+ base >= 4 && < 5+ , tasty >= 0.10+ , tasty-hunit >= 0.9+ , indentation flag Parsec description: Include indentation operators for Parsec
+ tests/ParensParsec.hs view
@@ -0,0 +1,86 @@+{-# LANGUAGE NoMonomorphismRestriction, FlexibleContexts #-}+module ParensParsec where++import Control.Applicative+import Text.Parsec+import Text.Parsec.Indentation+import Test.Tasty (TestTree, testGroup)+import Test.Tasty.HUnit (testCase, assertEqual, assertFailure, Assertion)+ ++data A+ = Par A -- '(' A ')'+ | Bra A -- '[' A ']'+ | Seq A A -- A A+ | Nil -- epsilon+ deriving (Show, Eq)++a :: (Monad m, Stream s m (Char, Indentation)) => ParsecT (IndentStream s) () m A+a = choice [ Seq <$> a' <*> a, a', return Nil ]++a' :: (Monad m, Stream s m (Char, Indentation)) => ParsecT (IndentStream s) () m A+a' = choice+ [ Par <$>+ between (localTokenMode (const Eq) $ char '(')+ (localTokenMode (const Eq) $ char ')')+ (localIndentation Gt a)+ , Bra <$>+ between (localTokenMode (const Ge) $ char '[')+ (localTokenMode (const Ge) $ char ']')+ (localIndentation Gt a)+ ]+++runParse input+ = case runParser a () "" (mkIndentStream 0 infIndentation True Gt input) of+ Left err -> Left (show err)+ Right a -> Right a++-- conveniences for tests+parL = Par . listToSeq+braL = Bra . listToSeq++listToSeq [] = Nil+listToSeq (x:xs) = Seq x $ listToSeq xs+ +input1 = [('(', 1),+ ('[', 4),+ ('(', 5),+ (')', 5),+ (']', 7),+ (')', 1)]+output1 = runParse input1+expected1 = listToSeq [ parL [braL [parL []]]+ ]++input2 = [('(', 1),+ ('[', 8),+ ('(', 6),+ (')', 6),+ ('[', 8),+ (']', 9),+ (']', 4),+ ('(', 3),+ (')', 3),+ (')', 1)]+output2 = runParse input2+expected2 = listToSeq [ parL [ braL [ parL []+ , braL []+ ]+ , parL []+ ]+ ]++assertParsedOk :: (Show err, Show a, Eq a) => Either err a -> a -> Assertion+assertParsedOk actual expected =+ case actual of+ Right ok -> assertEqual "parsing succeeded, but " expected ok+ Left err -> assertFailure ("parse failed with " ++ show err+ ++ ", expected" ++ show expected)++allTests :: TestTree+allTests =+ testGroup "parens (parsec)"+ [ testCase "1" $ assertParsedOk output1 expected1+ , testCase "2" $ assertParsedOk output2 expected2+ ]
+ tests/ParensTrifecta.hs view
@@ -0,0 +1,92 @@+module ParensTrifecta where++import Data.Monoid (Monoid(..))+import Control.Applicative++import Test.Tasty (TestTree, testGroup)+import Test.Tasty.HUnit (testCase, assertEqual, assertFailure, Assertion)++import Text.Trifecta+import Text.Trifecta.Indentation++data A+ = Par A -- '(' A ')'+ | Bra A -- '[' A ']'+ | Seq A A -- A A+ | Nil -- epsilon+ deriving (Show, Eq)++-- a :: (Monad m, Stream s m (Char, Indentation)) => ParsecT (IndentStream s) () m A+a :: (Applicative m, TokenParsing m, IndentationParsing m) => m A+a = choice [ Seq <$> a' <*> a, a', pure Nil ]++-- a' :: (Monad m, Stream s m (Char, Indentation)) => ParsecT (IndentStream s) () m A+a' :: (TokenParsing m, IndentationParsing m) => m A+a' = choice+ [ Par <$>+ between (localTokenMode (const Eq) $ symbolic '(')+ (localTokenMode (const Eq) $ symbolic ')')+ (localIndentation Gt a)+ , Bra <$>+ between (localTokenMode (const Ge) $ symbolic '[')+ (localTokenMode (const Ge) $ symbolic ']')+ (localIndentation Gt a)+ ]+++runParse input+ = let indA = evalIndentationParserT (a :: IndentationParserT Char Parser A)+ $ mkIndentationState 0 infIndentation True Gt+ in case parseString indA mempty input of+ Failure err -> Left (show err)+ Success a -> Right a++-- conveniences for tests+parL = Par . listToSeq+braL = Bra . listToSeq++listToSeq [] = Nil+listToSeq (x:xs) = Seq x $ listToSeq xs++input1 = unlines [ "("+ , " [("+ , " )"+ , " ]"+ , ")"+ ]+output1 = runParse input1+expected1 = listToSeq [ parL [braL [parL []]]+ ]++input2 = unlines [ "("+ , " ["+ , " ("+ , " )"+ , " []"+ , " ]"+ , " ("+ , " )"+ , ")"+ ]+output2 = runParse input2+expected2 = listToSeq [ parL [ braL [ parL []+ , braL []+ ]+ , parL []+ ]+ ]+++assertParsedOk :: (Show err, Show a, Eq a) => Either err a -> a -> Assertion+assertParsedOk actual expected =+ case actual of+ Right ok -> assertEqual "parsing succeeded, but " expected ok+ Left err -> assertFailure ("parse failed with " ++ show err+ ++ ", expected" ++ show expected)++allTests :: TestTree+allTests =+ testGroup "parens (trifecta)"+ [ testCase "1" $ assertParsedOk output1 expected1+ , testCase "2" $ assertParsedOk output2 expected2+ ]
+ tests/all-tests.hs view
@@ -0,0 +1,27 @@+{-# LANGUAGE CPP #-}+module Main where++import Test.Tasty (defaultMain, testGroup)+#if defined(ENABLE_PARSEC_TESTS)+import qualified ParensParsec +#endif+#if defined(ENABLE_TRIFECTA_TESTS)+import qualified ParensTrifecta+#endif ++#if defined(ENABLE_TRIFECTA_TESTS)+#endif++main =+ defaultMain $ testGroup "All tests" $+ [+#if defined(ENABLE_PARSEC_TESTS)+ ParensParsec.allTests+#endif+ ]+ +++ [+#if defined(ENABLE_TRIFECTA_TESTS)+ ParensTrifecta.allTests+#endif+ ]