packages feed

hspec-attoparsec (empty) → 0.1.0.0

raw patch · 6 files changed

+307/−0 lines, 6 filesdep +attoparsecdep +basedep +bytestringsetup-changed

Dependencies added: attoparsec, base, bytestring, hspec, hspec-expectations, text

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2014, Alp Mestanogullari++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Alp Mestanogullari nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ hspec-attoparsec.cabal view
@@ -0,0 +1,51 @@+name:                hspec-attoparsec+version:             0.1.0.0+synopsis:            Utility functions for testing your attoparsec parsers with hspec+description:         This package provides some helper functions for testing attoparsec parsers with hspec.+                     .+                     See the documentation in @Test.Hspec.Attoparsec@ for examples, or this package's own test suite.+homepage:            http://github.com/alpmestan/hspec-attoparsec+Bug-reports:         https://github.com/alpmestan/hspec-attoparsec/issues+license:             BSD3+license-file:        LICENSE+author:              Alp Mestanogullari+maintainer:          alpmestan@gmail.com+copyright:           2014 Alp Mestanogullari+category:            Testing, Parsing+build-type:          Simple+cabal-version:       >=1.10++library+  exposed-modules:     Test.Hspec.Attoparsec,+                       Test.Hspec.Attoparsec.Source+  build-depends:       base >=4 && <5,+                       attoparsec >= 0.10,+                       hspec-expectations >= 0.5,+                       bytestring >= 0.8,+                       text >= 1.0+  hs-source-dirs:      src+  default-language:    Haskell2010+  ghc-options:         -Wall++test-suite spec+  type:+      exitcode-stdio-1.0+  ghc-options:+      -Wall+  hs-source-dirs:+      src, tests+  main-is:+      Spec.hs+  build-depends:+      base    == 4.*+    , text >= 1.0+    , bytestring >= 0.8+    , hspec+    , hspec-expectations >= 0.5+    , attoparsec >= 0.10+  default-language:+      Haskell2010++source-repository head+  type: git+  location: http://github.com/alpmestan/hspec-attoparsec.git
+ src/Test/Hspec/Attoparsec.hs view
@@ -0,0 +1,125 @@+{-# LANGUAGE OverloadedStrings #-}+-- |+-- Module       : Test.Hspec.Attoparsec+-- Copyright    : (c) 2014 Alp Mestanogullari+-- License      : BSD3+-- Maintainer   : alpmestan@gmail.com+-- Stability    : experimental+-- +-- Utility functions for testing @attoparsec@ parsers, each one providing+-- an example of how to use it.+module Test.Hspec.Attoparsec+  ( -- * Equality-based combinator+    shouldParse++  , -- * Predicate-based combinator+    parseSatisfies++  , -- * Inspecting the result+    shouldSucceedOn+  , shouldFailOn++  , -- * Inspecting unconsumed input+    leavesUnconsumed++  , -- * The 'Source' class, connecting parsers and inputs+    Source(..)++  , -- * The 'Leftover' class, letting us inspect unconsumed input+    Leftover(..)+  ) where++import Control.Monad (when)+import Data.Either (isLeft, isRight)+import Test.Hspec.Attoparsec.Source+import Test.Hspec.Expectations++-- | Create an expectation by saying what the result should be.+--   Intended to be used with '~>' as follows:+--+-- >   "<!-- foo -->" ~> htmlCommentParser+-- >     `shouldParse` TagComment " foo "+shouldParse :: (Eq a, Show a) => Either String a -> a -> Expectation+res `shouldParse` expectedVal =+  either (expectationFailure . errmsg)+         checkEquality+         res++  where errmsg err =   "  expected: " ++ show expectedVal+                  ++ "\n  but parsing failed with error: " ++ err++        checkEquality parsedVal =+          when (parsedVal /= expectedVal) $+            expectationFailure $   "  expected: " ++ show expectedVal+                              ++ "\n  but got: " ++ show parsedVal++-- | Create an expectation by saying that the parser should successfully+--   parse a value and that this value should satisfy some predicate.+--   +--   This can fail if the parsing doesn't succeed or if it succeeds but+--   the value doesn't match the predicate.+--+-- > ">>>" ~> many (char '>')+-- >   `parseSatisfies` ((==3) . length)+parseSatisfies :: Show a => Either String a -> (a -> Bool) -> Expectation+parseSatisfies res predicate =+  either (expectationFailure . errmsg)+         checkPred+         res++  where errmsg err =   "  expected a parsed value to check against the predicate"+                  ++ "\n  but parsing failed with error: " ++ err++        checkPred value =+          when (not $ predicate value) $+            expectationFailure $   +                 "  the following value did not match the predicate: \n"+              ++ "  " ++ show value++-- | Check that a parser fails on some given input+--+-- > char 'x' `shouldFailOn` "a"+shouldFailOn :: (Source p s s' r, Show a)+             => p s' a+             -> s+             -> Expectation+parser `shouldFailOn` string =+  (string ~> parser) `shouldSatisfy` isLeft++-- | Check that a parser succeeds on some given input+--+-- > char 'x' `shouldSucceedOn` "x"+shouldSucceedOn :: (Source p s s' r, Show a)+                => p s' a+                -> s+                -> Expectation+parser `shouldSucceedOn` string =+  (string ~> parser) `shouldSatisfy` isRight++-- | Checking that the given parser succeeds+--   and yields the given part of the input unconsumed.+--   Intended to be used in conjunction with '~?>'+--+-- > ("xa" :: Text) ~?> char 'x'+-- >   `leavesUnconsumed` "a"+leavesUnconsumed :: (Source p s s' r, Leftover r s)+                 => r a+                 -> s+                 -> Expectation+leavesUnconsumed res str+  | unconsumed == Nothing && str /= "" =+      expectationFailure $ +           "  expected the parser to leave the following unconsumed: " ++ show str+      ++ "\n  but got no leftover"+  | otherwise = +      case unconsumed of+        Just str' -> +          when (str /= str') $+            expectationFailure $ +                   "  expected the parser to leave the following unconsumed: " ++ show str+              ++ "\n  but got: " ++ show str'+        Nothing -> expectationFailure $+                          "  expected the parser to leave the following unconsumed: " ++ show str+                     ++ "\n  but got no unconsumed input"++  where unconsumed = leftover res
+ src/Test/Hspec/Attoparsec/Source.hs view
@@ -0,0 +1,98 @@+{-# LANGUAGE MultiParamTypeClasses,+			 TypeSynonymInstances,+			 FlexibleInstances,+			 FunctionalDependencies #-}+-- |+-- Module       : Test.Hspec.Attoparsec.Source+-- Copyright    : (c) 2014 Alp Mestanogullari+-- License      : BSD3+-- Maintainer   : alpmestan@gmail.com+-- Stability    : experimental+-- +-- A 'Source' class that ties parser types and input types to+-- give you a uniform interface for testing your parsers,+-- without caring about the input type.+module Test.Hspec.Attoparsec.Source where ++import qualified Data.Attoparsec.ByteString as AB+import qualified Data.ByteString as B++import qualified Data.Attoparsec.ByteString.Lazy as ALB+import qualified Data.ByteString.Lazy as LB++import qualified Data.Attoparsec.Text as AT+import qualified Data.Text as T++import qualified Data.Attoparsec.Text.Lazy as ALT+import qualified Data.Text.Lazy as LT++import qualified Data.Attoparsec.Types as Atto++import Data.String (IsString)++-- | A class where each instance will just teach+--   how to get an Either or the specific result +--   type associated to the parser for the given+--   input type.+class (Eq string, Show string, IsString string)+   => Source parser string string' result | string -> parser, string -> result, string -> string' where+	-- | Feed some input to a parser and extract the result+	--   as either a failure 'String' or an actually parsed value.+	--   Can be read as /fed to/.+	-- +	-- > -- "<a ...>" fed to an HTML parser +	-- > "<a href=\"/foo\">Go to foo</a>" ~> htmlParser :: Either String a+	(~>) :: string -> parser string' a -> Either String a++	-- | Feed some input to a parser and extract it as the+	--   appropriate result type from that module.+	-- +	--   This is not currently useful in the library per se,+	--   but is used in test-suites directly where we generally only deal+	--   with one concrete set of parser, input and result types.+	--   This lets us inspect the result in any way we want, e.g+	--   in conjunction with @shouldSatisfy@ or a custom hspec combinator.+	(~?>) :: string -> parser string' a -> result a++instance Source Atto.Parser B.ByteString B.ByteString AB.Result where+	t ~> p = AB.parseOnly p t++	t ~?> p = AB.parse p t++instance Source Atto.Parser LB.ByteString B.ByteString ALB.Result where+	t ~> p = ALB.eitherResult $ t ~?> p++	t ~?> p = ALB.parse p t++instance Source Atto.Parser T.Text T.Text AT.Result where+	t ~> p = AT.parseOnly p t++	t ~?> p = AT.parse p t++instance Source Atto.Parser LT.Text T.Text ALT.Result where+	t ~> p = ALT.eitherResult $ t ~?> p++	t ~?> p = ALT.parse p t++-- | Class for generically inspecting unconsumed input+class Leftover r s | r -> s where+	-- | Get the unconsumed input from the result of a parser+	--   +	--   Returns 'Nothing' if the unconsumed input is ""+	leftover :: r a -> Maybe s++instance Leftover AB.Result B.ByteString where+	leftover (AB.Done t _) = Just t+	leftover _             = Nothing++instance Leftover ALB.Result LB.ByteString where+	leftover (ALB.Done t _) = Just t+	leftover _              = Nothing++instance Leftover AT.Result T.Text where+	leftover (AT.Done t _) = Just t+	leftover _            = Nothing++instance Leftover ALT.Result LT.Text where+	leftover (ALT.Done t _) = Just t+	leftover _              = Nothing
+ tests/Spec.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}